A
要麼所有人全部做左邊的筷子,要麼全部右邊的筷子。依次處理。
大家按照順序拿筷子,如果成立,當前的人,所需方向的筷子肯定沒拿。如果所需方向的反方向的筷子被拿了,就結果*2(第一選擇方向可以任選);反而,肯定要求第一選擇方向是所需方向,就結果*1。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 using namespace std; 17 #define ll long long 18 #define ull unsigned long long 19 20 21 const ll mod=998244353; 22 23 const double eps_1=1e-5; 24 const double eps_2=1e-10; 25 26 const int maxn=2e5+10; 27 28 bool vis[maxn]; 29 char str[maxn]; 30 int n,fx,a[maxn]; 31 ll result=0; 32 33 void handle() 34 { 35 int i,d,left,right,mode; 36 ll ans=1; 37 38 for (i=1;i<=n;i++) 39 { 40 d=a[i]; 41 42 left=d-1; 43 if (left==0) 44 left=n; 45 right=d+1; 46 if (right==n+1) 47 right=1; 48 49 if (str[d]=='L') 50 mode=1; 51 else if (str[d]=='R') 52 mode=2; 53 else 54 mode=0; 55 56 if (fx==1) 57 { 58 if (!vis[right] && mode==2) 59 return; 60 if (vis[right] && mode==0) 61 ans=ans*2%mod; 62 } 63 else 64 { 65 if (!vis[left] && mode==1) 66 return; 67 if (vis[left] && mode==0) 68 ans=ans*2%mod; 69 } 70 vis[d]=1; 71 } 72 73 result=(result+ans)%mod; 74 } 75 76 int main() 77 { 78 int i; 79 scanf("%d",&n); 80 for (i=1;i<=n;i++) 81 scanf("%d",&a[i]); 82 scanf("%s",str+1); 83 84 for (fx=0;fx<=1;fx++) 85 { 86 memset(vis,0,sizeof(vis)); 87 handle(); 88 } 89 90 printf("%lld", result); 91 92 return 0; 93 }
B
左括號,右括號數目= x,y
1. abs(x-y)/2,肯定就是修改的(->) 、 )->( 的數目。如果是)->(,一開始把“最左邊”的這些')'改成’('。
2. (->) 、 )->( 花費為B,也可以花費為2*A的方式解決
3. 從左到右,記錄 '(' - ')' 的數目,找出有')‘,使得 '(' - ')' = -1的情況,這時候需要B/2A了。')‘->'('後,'(' - ')'變為1。記錄最少需要B/2A的次數。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cstdbool> #include <string> #include <algorithm> #include <iostream> #include <sstream> #include <ctime> #include <stack> #include <vector> #include <queue> #include <set> #include <map> using namespace std; #define ll long long #define ull unsigned long long const ll mod_1=1e9+7; const ll mod_2=998244353; const double eps_1=1e-5; const double eps_2=1e-10; const int maxn=1e6+10; char str[maxn]; int main() { int n,len,i; ll cha=0,jia_cnt=0,cnt_lower_zero=0,a,b; //ll result=0; scanf("%d%lld%lld",&n,&a,&b); scanf("%s",str); len=strlen(str); for (i=0;i<len;i++) if (str[i]=='(') cha++; else cha--; if (cha<0) jia_cnt=abs(cha); cha=abs(cha)/2; for (i=0;i<len;i++) { if (str[i]==')') jia_cnt--; else jia_cnt++; if (jia_cnt<0) { jia_cnt=1; cnt_lower_zero++; } } if (a>b*2) printf("%lld",(cha+cnt_lower_zero*2) *b ); else printf("%lld",cha*b + cnt_lower_zero*a ); return 0; } /* ((((((((( ))))) 3 2 2 (((((( 3 10 2 (((((( 3 2 10 (((((( 3 2 2 )))))) 3 2 10 )))))) 3 2 10 )))((( 3 10 2 )))((( 3 2 2 )))((( */
C
遇到這種題很頭疼,很容易找不到錯誤的地方,製造不出可以找到錯誤的樣例。
這種題目應該先多製造幾個樣例,然後把一些條理理清楚了再寫會比較好
官方題解看著有點暈,也看到寫得特別短的程式碼,有點不理解……
我的是,把這些分為[l1,r1] [l2,r2] [l3,r3] ... [lk,rk]的區間,它們互不交集。然後區間有升有降。
如果l_{i-1} -> l_{i} -> l_{i+1} 是降、升的趨勢,那麼這個區間的數值應該選擇r_{i},還有最左邊和最右邊的區間要做特殊處理,其它都選擇l_{i}。
對於一個區間,它相對於上個區間是升的話,然後這個區間最左邊的幾個數值可以往上個區間那個靠,這是為了讓字典序最小,只要滿足條件即可。
同理,對於一個區間,它相對於下個區間是降的話,然後這個區間最右邊的幾個數值可以往下個區間那個靠,這是為了讓字典序最小,只要滿足條件即可。
1 /* 2 1 製造比較小的隨機資料 3 10以內的 4 2 然後用std程式跑結果 5 */ 6 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <cmath> 11 #include <cstdbool> 12 #include <string> 13 #include <algorithm> 14 #include <iostream> 15 #include <sstream> 16 #include <ctime> 17 #include <stack> 18 #include <vector> 19 #include <queue> 20 #include <set> 21 #include <map> 22 using namespace std; 23 24 const double eps_1=1e-5; 25 const double eps_2=1e-10; 26 27 const int maxn=5e5+10; 28 29 30 31 32 int l[maxn],r[maxn],v[maxn],result[maxn]; 33 int ql[maxn],qr[maxn],range[maxn]; 34 35 int main() 36 { 37 int inf=1e9+10; 38 int n,i,j,k,o,ll=-inf,rr=inf,cnt=1,temp; 39 range[0]=0; 40 scanf("%d",&n); 41 for (i=1;i<=n;i++) 42 { 43 scanf("%d%d",&l[i],&r[i]); 44 45 if (r[i]<ll || l[i]>rr) 46 { 47 range[cnt]=i-1; 48 ql[cnt]=ll; 49 qr[cnt]=rr; 50 51 ll=l[i]; 52 rr=r[i]; 53 cnt++; 54 } 55 56 ll=max(ll, l[i]); 57 rr=min(rr, r[i]); 58 } 59 60 ql[cnt]=ll; 61 qr[cnt]=rr; 62 range[cnt]=n; 63 64 65 66 67 for (i=1;i<=cnt;i++) 68 v[i]=ql[i]; 69 70 if (cnt!=1) 71 { 72 73 i=1; 74 while (i<cnt) 75 { 76 if (i<cnt && ql[i]>ql[i+1]) 77 { 78 while (ql[i]>ql[i+1]) 79 i++; 80 if (i!=cnt) 81 v[i]=qr[i]; 82 } 83 i++; 84 } 85 86 if (ql[1]<ql[2]) 87 v[1]=qr[1]; 88 89 if (ql[cnt-1]>ql[cnt]) 90 v[cnt]=qr[cnt]; 91 } 92 93 94 for (i=1 ;i<=cnt;i++) 95 { 96 if (i!=1 && v[i]>v[i-1]) 97 { 98 temp = l[ range[i-1]+1 ]; 99 for (o=range[i-1]+1 ; o<=range[i] ; o++) 100 { 101 if (l[o]>temp) 102 temp=l[o]; 103 if (temp==v[i]) 104 break; 105 result[o]=temp; 106 } 107 } 108 else 109 o=range[i-1]+1; 110 111 if (i!=cnt && v[i]>v[i+1]) 112 { 113 temp = v[i+1]; 114 for (k=range[i] ; k>=o ; k--) 115 { 116 if (l[k]>temp) 117 temp=l[k]; 118 if (temp==v[i]) 119 break; 120 result[k]=temp; 121 } 122 } 123 else 124 k=range[i]; 125 126 for (j=o ; j<=k ; j++) 127 result[j]=v[i]; 128 129 } 130 131 for (i=1;i<=n;i++) 132 { 133 printf("%d",result[i]); 134 if (i!=n) 135 printf(" "); 136 } 137 138 return 0; 139 } 140 /* 141 15 142 5 29 143 9 28 144 15 19 145 4 26 146 7 23 147 10 13 148 12 25 149 3 11 150 6 17 151 1 21 152 24 27 153 2 8 154 14 18 155 20 22 156 16 30 157 158 159 160 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20 161 162 163 164 165 166 5 167 50 60 168 40 50 169 30 40 170 20 30 171 10 20 172 173 5 174 10 20 175 20 30 176 30 40 177 40 50 178 50 60 179 180 2 181 10 30 182 40 60 183 184 2 185 40 60 186 10 30 187 188 5 189 100 200 190 300 400 191 500 600 192 50 70 193 20 40 194 195 */
1 /* 2 1 製造比較小的隨機資料 3 10以內的 4 2 然後用std程式跑結果 5 */ 6 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <cmath> 11 #include <cstdbool> 12 #include <string> 13 #include <algorithm> 14 #include <iostream> 15 #include <sstream> 16 #include <ctime> 17 #include <stack> 18 #include <vector> 19 #include <queue> 20 #include <set> 21 #include <map> 22 using namespace std; 23 24 const double eps_1=1e-5; 25 const double eps_2=1e-10; 26 27 const int maxn=5e5+10; 28 29 30 int l[maxn],r[maxn],v[maxn],result[maxn]; 31 int ql[maxn],qr[maxn],range[maxn]; 32 33 int main() 34 { 35 int inf=1e9+10; 36 int n,i,j,ll=-inf,rr=inf,cnt=0,temp; 37 range[0]=0; 38 scanf("%d",&n); 39 for (i=1;i<=n;i++) 40 { 41 scanf("%d%d",&l[i],&r[i]); 42 43 if (r[i]<ll || l[i]>rr) 44 { 45 ++cnt; 46 range[cnt]=i-1; 47 ql[cnt]=ll; 48 qr[cnt]=rr; 49 50 ll=-inf,rr=inf; 51 } 52 53 ll=max(ll, l[i]); 54 rr=min(rr, r[i]); 55 } 56 57 ++cnt; 58 range[cnt]=n; 59 ql[cnt]=ll; 60 qr[cnt]=rr; 61 62 63 for (i=1;i<=cnt;i++) 64 if (cnt!=1 && ((i==1 || ql[i]<ql[i-1]) && (i==cnt || ql[i]<ql[i+1]))) 65 v[i]=qr[i]; 66 else 67 v[i]=ql[i]; 68 j=1; 69 for (i=1;i<=n;i++) 70 { 71 result[i]=v[j]; 72 if (j!=cnt && i==range[j]) 73 j++; 74 } 75 76 for (i=1;i<=cnt;i++) 77 { 78 //asc 79 if (i!=1 && v[i]>v[i-1]) 80 { 81 j=range[i-1]+1; 82 temp = v[i-1]; 83 while (temp<ql[i]) 84 { 85 temp=max(temp,l[j]); 86 result[j]=temp; 87 j++; 88 } 89 } 90 91 //des 92 if (i!=cnt && v[i]>v[i+1]) 93 { 94 j=range[i]; 95 temp=v[i+1]; 96 while (temp<ql[i]) 97 { 98 temp=max(temp,l[j]); 99 result[j]=temp; 100 j--; 101 } 102 } 103 } 104 105 for (i=1;i<=n;i++) 106 { 107 printf("%d",result[i]); 108 if (i!=n) 109 printf(" "); 110 } 111 112 return 0; 113 } 114 /* 115 15 116 5 29 117 9 28 118 15 19 119 4 26 120 7 23 121 10 13 122 12 25 123 3 11 124 6 17 125 1 21 126 24 27 127 2 8 128 14 18 129 20 22 130 16 30 131 132 133 134 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20 135 136 137 138 139 140 5 141 50 60 142 40 50 143 30 40 144 20 30 145 10 20 146 147 5 148 10 20 149 20 30 150 30 40 151 40 50 152 50 60 153 154 2 155 10 30 156 40 60 157 158 2 159 40 60 160 10 30 161 162 5 163 100 200 164 300 400 165 500 600 166 50 70 167 20 40 168 169 */
把樣例裡的數值離散化,方便看得清
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 using namespace std; 17 #define ll long long 18 #define ull unsigned long long 19 20 const ll mod_1=1e9+7; 21 const ll mod_2=998244353; 22 23 const double eps_1=1e-5; 24 const double eps_2=1e-10; 25 26 const int maxn=30+10; 27 28 29 int a[maxn],b[maxn],c[maxn],r[maxn]; 30 map<int,int> map_1; 31 32 33 int main() 34 { 35 int n,i,j=0; 36 scanf("%d",&n); 37 for (i=1;i<=n;i++) 38 { 39 scanf("%d%d",&a[i],&b[i]); 40 c[i*2-1]=a[i]; 41 c[i*2]=b[i]; 42 } 43 for (i=1;i<=n;i++) 44 scanf("%d",&r[i]); 45 sort(c+1,c+2*n+1); 46 c[0]=-1; 47 for (i=1;i<=2*n;i++) 48 if (c[i]!=c[i-1]) 49 { 50 j++; 51 map_1[ c[i] ] = j; 52 } 53 54 for (i=1;i<=n;i++) 55 printf("%d %d\n",map_1[ a[i] ], map_1[ b[i] ]); 56 printf("\n\n\n"); 57 for (i=1;i<=n;i++) 58 printf("%d ",map_1[ r[i] ]); 59 60 return 0; 61 } 62 /* 63 5 29 64 9 28 65 15 19 66 4 26 67 7 23 68 10 13 69 12 25 70 3 11 71 6 17 72 1 21 73 24 27 74 2 8 75 14 18 76 20 22 77 16 30 78 79 80 81 82 5 29 83 9 28 84 15 19 85 4 26 86 7 23 87 10 13 88 12 25 89 3 11 90 6 17 91 1 21 92 24 27 93 2 8 94 14 18 95 20 22 96 16 30 97 98 99 100 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20 101 */
建立小的資料
1 /* 2 10以內資料 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdbool> 9 #include <string> 10 #include <algorithm> 11 #include <iostream> 12 #include <sstream> 13 #include <ctime> 14 #include <stack> 15 #include <vector> 16 #include <queue> 17 #include <set> 18 #include <map> 19 using namespace std; 20 #define ll long long 21 #define ull unsigned long long 22 23 const ll mod_1=1e9+7; 24 const ll mod_2=998244353; 25 26 const double eps_1=1e-5; 27 const double eps_2=1e-10; 28 29 const int maxn=2e5+10; 30 31 32 33 34 35 36 int main() 37 { 38 int n=30,range=30,i,x,y; 39 srand((int)time(0)); 40 printf("%d\n",n); 41 42 for (i=1;i<=n;i++) 43 { 44 x=rand()%range; 45 y=rand()%range; 46 if (x>y) 47 swap(x,y); 48 printf("%d %d\n",x,y); 49 } 50 51 52 return 0; 53 }
暴力用程式獲取小資料的輸出結果
比如資料l_i,r_i在1-x範圍內
然後結果可以是(r_i - l_i + 1) ^n種,然後在最小化的情況下,最小序列的輸出
複雜度(r_i - l_i + 1) ^n
9個l_i-r_i範圍為1-10的資料
12個l_i-r_i範圍為1-5的資料
17個l_i-r_i範圍為1-3的資料
看著也勉強還行
如果真要到這種地步的話
如果是賽後,對著test case或者是用別人的std程式碼跑一些樣例出來
D
ABC165_F_LIS_on_Tree
LIS,二分,當前數值修改到這個當下最長子序列對應的位置
樹,dfs,當前位置,前修改,最後修改回來
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 using namespace std; 17 #define LL long long 18 #define ULL unsigned long long 19 20 const LL mod_1=1e9+7; 21 const LL mod_2=998244353; 22 23 const double eps_1=1e-5; 24 const double eps_2=1e-10; 25 26 const int maxn=2e5+10; 27 28 int a[maxn], f[maxn], result[maxn], cnt=0; 29 30 vector<int> adj[maxn], child[maxn]; 31 bool hap[maxn]; 32 33 void find_child(int d) 34 { 35 hap[d]=1; 36 for (auto chi:adj[d]) 37 if (!hap[chi]) 38 { 39 child[d].push_back(chi); 40 find_child(chi); 41 } 42 } 43 44 void dfs(int d) 45 { 46 int pre_f_ith, pre_cnt = cnt; 47 48 int ith = lower_bound(f, f+cnt, a[d]) - f; 49 pre_f_ith = f[ith]; 50 f[ith] = a[d]; 51 if (ith>=cnt) 52 cnt++; 53 result[d] = cnt; 54 55 for (auto chi:child[d]) 56 dfs(chi); 57 58 cnt = pre_cnt; 59 f[ith] = pre_f_ith; 60 } 61 62 int main() 63 { 64 int n,i,x,y; 65 memset(hap,0,sizeof(hap)); 66 scanf("%d",&n); 67 for (i=1;i<=n;i++) 68 scanf("%d",&a[i]); 69 for (i=1;i<n;i++) 70 { 71 scanf("%d%d",&x,&y); 72 adj[x].push_back(y); 73 adj[y].push_back(x); 74 } 75 76 f[0]=0; 77 find_child(1); 78 dfs(1); 79 80 for (i=1;i<=n;i++) 81 printf("%d\n",result[i]); 82 83 return 0; 84 } 85 /* 86 5 87 1 2 3 4 5 88 1 2 89 2 3 90 3 4 91 4 5 92 93 94 5 95 5 4 3 2 1 96 1 2 97 2 3 98 3 4 99 4 5 100 101 1 102 1 103 104 5 105 10 10 10 10 10 106 1 2 107 2 3 108 3 4 109 4 5 110 111 112 7 113 7 9 9 11 11 10 10 114 1 2 115 2 3 116 3 4 117 4 5 118 5 6 119 6 7 120 121 */
/*1 製造比較小的隨機資料10以內的2 然後用std程式跑結果*/
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <cstdbool>#include <string>#include <algorithm>#include <iostream>#include <sstream>#include <ctime>#include <stack>#include <vector>#include <queue>#include <set>#include <map>using namespace std;
const double eps_1=1e-5;const double eps_2=1e-10;
const int maxn=5e5+10;
int l[maxn],r[maxn],v[maxn],result[maxn];int ql[maxn],qr[maxn],range[maxn];
int main(){ int inf=1e9+10; int n,i,j,k,o,ll=-inf,rr=inf,cnt=1,temp; range[0]=0; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d%d",&l[i],&r[i]);
if (r[i]<ll || l[i]>rr) { range[cnt]=i-1; ql[cnt]=ll; qr[cnt]=rr;
ll=l[i]; rr=r[i]; cnt++; }
ll=max(ll, l[i]); rr=min(rr, r[i]); }
ql[cnt]=ll; qr[cnt]=rr; range[cnt]=n;
for (i=1;i<=cnt;i++) v[i]=ql[i];
if (cnt!=1) {
i=1; while (i<cnt) { if (i<cnt && ql[i]>ql[i+1]) { while (ql[i]>ql[i+1]) i++; if (i!=cnt) v[i]=qr[i]; } i++; }
if (ql[1]<ql[2]) v[1]=qr[1];
if (ql[cnt-1]>ql[cnt]) v[cnt]=qr[cnt]; }
for (i=1 ;i<=cnt;i++) { if (i!=1 && v[i]>v[i-1]) { temp = l[ range[i-1]+1 ]; for (o=range[i-1]+1 ; o<=range[i] ; o++) { if (l[o]>temp) temp=l[o]; if (temp==v[i]) break; result[o]=temp; } } else o=range[i-1]+1;
if (i!=cnt && v[i]>v[i+1]) { temp = v[i+1]; for (k=range[i] ; k>=o ; k--) { if (l[k]>temp) temp=l[k]; if (temp==v[i]) break; result[k]=temp; } } else k=range[i];
for (j=o ; j<=k ; j++) result[j]=v[i];
}
for (i=1;i<=n;i++) { printf("%d",result[i]); if (i!=n) printf(" "); }
return 0;}/*155 299 2815 194 267 2310 1312 253 116 171 2124 272 814 1820 2216 30
15 15 15 12 12 12 12 11 11 11 24 8 14 20 20
550 6040 5030 4020 3010 20
510 2020 3030 4040 5050 60
210 3040 60
240 6010 30
5100 200300 400500 60050 7020 40
*/