mix
1 //polya burnside定理 http://blog.csdn.net/liangzhaoyang1/article/details/72639208 2 //原题ASIA qingdao https://nanti.jisuanke.com/t/18515 3 #include <iostream> 4 #include <map> 5 #include <algorithm> 6 #include <cstring> 7 8 using namespace std; 9 10 map<string, bool> vis; 11 int tot; 12 const int LEN = 16; 13 int oo[3][LEN] = {//翻转 旋转 扭转 14 {0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5, 12, 13, 15, 14}, 15 {13, 12, 4, 2, 5, 3, 15, 14, 9, 11, 8, 10, 6, 7, 0, 1}, 16 {1, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 14, 15, 12, 13} 17 }; 18 bool cir[LEN+5]; 19 char sss[LEN+5]; 20 int cnts[LEN+5]={0}; 21 22 int cnt(string &s){ 23 int res = 0; 24 memset(cir,0,sizeof(cir)); 25 int f; 26 for(int i = 0; i < LEN; i++){ 27 if(!cir[i]){ 28 cir[i] = true; 29 f = i; 30 while(!cir[f = s[f]-'A']){ 31 cir[f] = true; 32 } 33 res++; 34 } 35 } 36 return res; 37 } 38 39 void bfs(string s){ 40 if(vis[s]) return; 41 tot++; 42 vis[s] = true; 43 cnts[cnt(s)]++; 44 string ss = s; 45 for(int i = 0; i < 3; i++){ 46 for(int k = 0; k < LEN; k++){ 47 s[k] = ss[oo[i][k]]; 48 } 49 bfs(s); 50 } 51 } 52 53 int main(){ 54 tot = 0; 55 for(int i = 0; i < LEN; i++) 56 sss[i] = i+'A'; 57 sss[LEN] = '\0'; 58 string s = sss; 59 bfs(s); 60 int n; 61 while(cin >> n){ 62 long long ans = 0; 63 long long p = 1; 64 for(int i = 1; i <= LEN; i++){ 65 p *= n; 66 ans += cnts[i]*p; 67 } 68 ans /= tot; 69 cout << ans << endl; 70 } 71 return 0; 72 }
1 //polya hdu3923 2 // https://www.cnblogs.com/lxjshuju/p/6824210.html 3 #include <bits/stdc++.h> 4 5 using namespace std; 6 typedef long long LL; 7 const LL mod=1000000007; 8 9 LL gcd(LL a, LL b){ 10 return b==0?a:gcd(b,a%b); 11 } 12 13 LL power(LL p, LL n){ 14 LL ans = 1; 15 while(n){ 16 if(n&1) 17 ans = ans*p%mod; 18 p = p*p%mod; 19 n/=2; 20 } 21 return ans; 22 } 23 24 LL exgcd(LL a, LL b, LL &x, LL &y){ 25 if(!b){ 26 x = 1; 27 y = 0; 28 return a; 29 } 30 LL d = exgcd(b,a%b,x,y); 31 LL t = x; 32 x = y; 33 y = t - a/b*y; 34 return d; 35 } 36 37 int main(){ 38 int T; 39 cin >> T; 40 int q = 0; 41 while(T--){ 42 LL ans = 0; 43 LL n,m; 44 cin >> n >> m; 45 for(LL i = 1; i <= m; i++){ 46 ans += power(n,gcd(m,i)); 47 ans%=mod; 48 } 49 if(m&1) 50 ans += (m*power(n,m/2+1))%mod; 51 else 52 ans += ((m/2*power(n,m/2+1))%mod+(m/2*power(n,m/2))%mod); 53 ans %= mod; 54 LL x, y; 55 exgcd(2*m,mod,x,y); 56 //x=power(2*n,mod-2)%mod;//另外一种,费马小定理 57 x = (x+mod)%mod; 58 cout << "Case #" << ++q <<": "<< ans*x%mod << endl; 59 } 60 return 0; 61 }
1 //poj3070 2 //矩阵快速幂 3 //http://blog.csdn.net/wust_zzwh/article/details/52058209 4 //https://www.cnblogs.com/Commence/p/3976132.html 5 #include <iostream> 6 using namespace std; 7 8 struct mat{ 9 int D[3][3]; 10 }; 11 mat d; 12 13 mat xx(mat x, mat y){ 14 mat z; 15 for(int k = 0; k < 2; k++) 16 for(int i = 0; i < 2; i++) 17 z.D[i][k] = 0; 18 for(int k = 0; k < 2; k++){ 19 for(int i = 0; i < 2; i++){ 20 for(int j = 0; j < 2; j++){ 21 z.D[i][j] += x.D[i][k] * y.D[k][j]; 22 z.D[i][j] %= 10000; 23 } 24 } 25 } 26 return z; 27 } 28 29 int power(mat a, int b){ 30 mat ans; 31 for(int k = 0; k < 2; k++) 32 for(int i = 0; i < 2; i++) 33 ans.D[i][k] = (i==k); 34 while(b){ 35 if(b&1) 36 ans = xx(ans,a); 37 a = xx(a,a); 38 b/=2; 39 } 40 return ans.D[0][1]; 41 } 42 43 int solve(int t){ 44 d.D[0][0] = d.D[1][0] = d.D[0][1] = 1; 45 d.D[1][1] = 0; 46 int ans = 0; 47 ans = power(d,t); 48 return ans; 49 } 50 51 int main(){ 52 int k; 53 while(cin >> k && k>=0){ 54 cout << solve(k) << endl; 55 } 56 return 0; 57 }
1 //poj3233 矩阵快速幂 2 //https://www.cnblogs.com/hadilo/p/5903514.html 3 #include <stdio.h> 4 5 struct mat{ 6 int dd[70][70]; 7 }D,d; 8 9 int n, k, m; 10 11 mat xx(mat x, mat y){ 12 mat c; 13 for(int k = 0; k < n; k++) 14 for(int i = 0; i < n; i++) 15 c.dd[k][i] = 0; 16 for(int k = 0; k < n; k++){ 17 for(int i = 0; i < n; i++){ 18 if(x.dd[i][k] <= 0) 19 continue; 20 for(int j = 0; j < n; j++){ 21 if(y.dd[k][j] <= 0) 22 continue; 23 c.dd[i][j] += x.dd[i][k] * y.dd[k][j]; 24 c.dd[i][j] %= m; 25 } 26 } 27 } 28 return c; 29 } 30 31 void power(mat a, int b){ 32 while(b){ 33 if(b&1){ 34 d = xx(d,a); 35 } 36 a = xx(a,a); 37 b/=2; 38 } 39 } 40 41 int main(){ 42 while(~scanf("%d%d%d",&n,&k,&m)){ 43 for(int i = 0; i < n; i++){ 44 for(int j = 0; j < n; j++) 45 scanf("%d",&D.dd[i][j]); 46 D.dd[i][i+n] = D.dd[i+n][i+n] = d.dd[i][i] = d.dd[i+n][i+n] = 1; 47 } 48 n*=2; 49 k++; 50 power(D,k); 51 n/=2; 52 for(int i = 0; i < n; i++) 53 d.dd[i][i+n]= (d.dd[i][i+n]-1+m)%m; 54 for(int i = 0; i < n; i++){ 55 for(int k = 0; k < n; k++){ 56 if(k!=0) 57 printf(" "); 58 printf("%d", d.dd[i][k+n]); 59 } 60 printf("\n"); 61 } 62 } 63 return 0; 64 }
1 //快速幂 hdu2276 2 //https://www.cnblogs.com/zzqc/p/7152684.html 3 //注意左乘和右乘矩阵,矩阵的方向,矩阵的初始化 4 #include <stdio.h> 5 #include <cstring> 6 7 struct mat{ 8 int d[102][102]; 9 }; 10 int len; 11 int t[102]; 12 int n; 13 14 mat xx(mat x, mat y){ 15 mat z; 16 for(int k = 0; k < len; k++) 17 for(int i = 0; i < len; i++) 18 z.d[i][k] = 0; 19 for(int k = 0; k < len; k++){ 20 for(int i = 0; i < len; i++){ 21 for(int j = 0; j < len; j++){ 22 z.d[i][j] += x.d[i][k] * y.d[k][j]; 23 z.d[i][j] %= 2; 24 } 25 } 26 } 27 return z; 28 } 29 30 mat power(mat x, int y){ 31 mat ans; 32 for(int k = 0; k < len; k++) 33 for(int i = 0; i < len; i++) 34 ans.d[i][k] = (i==k); 35 while(y){ 36 if(y&1){ 37 ans = xx(ans,x); 38 } 39 x = xx(x,x); 40 y/=2; 41 } 42 return ans; 43 } 44 45 void solve(){ 46 mat a; 47 for(int k = 0; k < len; k++) 48 for(int i = 0; i < len; i++) 49 a.d[i][k] = 0; 50 a.d[len-1][0] = a.d[0][0] = 1; 51 for(int i = 1; i < len; i++){ 52 a.d[i-1][i] = a.d[i][i] = 1; 53 } 54 a = power(a,n); 55 for(int i = 0; i < len; i++){ 56 int z = 0; 57 for(int k = 0; k < len; k++){ 58 z += t[k] * a.d[k][i]; 59 z %= 2; 60 } 61 printf("%d", z); 62 }printf("\n"); 63 } 64 65 int main(){ 66 while(~scanf("%d",&n)){ 67 char s[102]; 68 scanf("%s",s); 69 len = strlen(s); 70 for(int i = 0; i < len; i++) 71 t[i] = s[i] - '0'; 72 solve(); 73 } 74 return 0; 75 }
1 //欧拉回路 Hdu3018 2 //http://www.cnblogs.com/buptLizer/archive/2012/04/15/2450297.html 3 // 4 #include <iostream> 5 using namespace std; 6 7 int deg[100010]; 8 int n,m; 9 int f[100010],odd[100010],cir[100010]; 10 bool used[100010]; 11 12 void init(){ 13 for(int i = 0; i <= n; i++){ 14 deg[i] = 0; 15 used[i] = false; 16 odd[i] = 0; 17 f[i] = i; 18 cir[i] = 0; 19 } 20 } 21 22 int find(int a){ 23 return f[a]==a?a:f[a] = find(f[a]); 24 } 25 26 void unite(int a, int b){ 27 int a1 = find(a), b1 = find(b); 28 if(a1==b1) 29 return; 30 f[a1] = b1; 31 } 32 33 int main(){ 34 while(cin >> n >> m){ 35 init(); 36 int a,b; 37 for(int i = 0; i < m; i++){ 38 cin >> a >> b; 39 deg[a]++; 40 deg[b]++; 41 unite(a,b); 42 } 43 int cnt = 0; 44 for(int i = 1; i <= n; i++){//注意是从1开始 45 int t = find(i); 46 if(!used[t]){ 47 used[t] = true; 48 cir[cnt++] = t; 49 } 50 if(deg[i]%2==1) 51 odd[t]++; 52 } 53 54 int ans = 0; 55 for(int i = 0; i < cnt; i++){ 56 if(deg[cir[i]]==0) 57 continue; 58 if(odd[cir[i]]==0) 59 ans++; 60 else 61 ans += odd[cir[i]]/2; 62 } 63 cout << ans << endl; 64 } 65 return 0; 66 }
1 //poj2230 欧拉回路 2 #include <stdio.h> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 struct Edge{ 8 int to, next; 9 }edge[100005]; 10 11 int head[10005],used[100005],n,m,cnt; 12 13 void add(int x, int y){ 14 edge[cnt].to = y; 15 edge[cnt].next = head[x]; 16 head[x] = cnt++; 17 } 18 19 void dfs(int u){ 20 for(int i = head[u]; i!=-1; i=edge[i].next){ 21 int v = edge[i].to; 22 if(!used[i]){ 23 used[i] = 1; 24 dfs(v); 25 } 26 } 27 printf("%d\n", u); 28 } 29 30 int main(){ 31 while(~scanf("%d%d",&n,&m)){ 32 cnt = 1; 33 memset(head,-1,sizeof(head)); 34 memset(used,0,sizeof(used)); 35 int x, y; 36 while(m--){ 37 scanf("%d%d",&x,&y); 38 add(x,y); 39 add(y,x); 40 } 41 dfs(1); 42 } 43 return 0; 44 }
1 //poj1386 欧拉回路 2 //http://www.cnblogs.com/buptLizer/archive/2012/04/15/2450297.html 3 #include <iostream> 4 #include <stdio.h> 5 #include <cstring> 6 using namespace std; 7 8 int in[30],out[30]; 9 int f[30]; 10 int _rank[30]; 11 bool used[30]; 12 int n; 13 14 void init(){ 15 for(int i = 0; i < 30; i++){ 16 _rank[i] = 1; 17 f[i] = -1; 18 in[i] = 0; 19 out[i] = 0; 20 used[i] = false; 21 } 22 } 23 24 int find(int a){ 25 if(f[a]>=0) 26 return f[a] = find(f[a]); 27 return a; 28 } 29 30 void unite(int x, int y){ 31 int a = find(x), b = find(y); 32 if(a==b) 33 return; 34 if(_rank[a] < _rank[b]){ 35 f[a] = b; 36 }else{ 37 f[b] = a; 38 if(_rank[a]==_rank[b]) 39 _rank[a]++; 40 } 41 return; 42 } 43 44 int main(){ 45 int t; 46 cin >> t; 47 while(t--){ 48 init(); 49 cin >> n; 50 for(int i = 0; i < n; i++){ 51 char a[1010]; 52 scanf("%s",a); 53 int len = strlen(a); 54 int x = a[0] - 'a'; 55 = used[y] = true; 56 out[x]++; 57 in[y]++; 58 unite(x,y); 59 } 60 int cir = 0; 61 for(int i = 0; i < 30; i++){ 62 if(used[i] && f[i]<0){ 63 cir++; 64 } 65 } 66 if(cir > 1){ 67 cout << "The door cannot be opened." <<endl; 68 continue; 69 } 70 int j = 0, k = 0, i; 71 for(i = 0; i < 30; i++){ 72 if(used[i] && in[i]!=out[i]){ 73 if(in[i]-out[i]==1) 74 j++; 75 else if(out[i]-in[i]==1) 76 k++; 77 else break; 78 } 79 } 80 if(i<30) 81 cout << "The door cannot be opened." <<endl; 82 else if(!(j+k) || (j==1&&k==1)) 83 cout << "Ordering is possible." <<endl; 84 else 85 cout << "The door cannot be opened." <<endl; 86 } 87 return 0; 88 }
1 //Poj2337 欧拉回路 2 #include <stdio.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <string> 6 #include <math.h> 7 #include <string.h> 8 9 using namespace std; 10 11 struct E{ 12 int to,next,index; 13 bool flag; 14 }edge[2010]; 15 16 int cnt; 17 int head[30], in[30], out[30]; 18 string s[1010]; 19 int tot, start; 20 int ans[1010]; 21 22 void add(int a, int b, int index){ 23 edge[tot].to = b; 24 edge[tot].next = head[a]; 25 edge[tot].flag = false; 26 edge[tot].index = index; 27 head[a] = tot++; 28 } 29 30 void dfs(int t){ 31 for(int i = head[t]; i!=-1; i = edge[i].next){ 32 if(!edge[i].flag){ 33 edge[i].flag = true; 34 dfs(edge[i].to); 35 ans[cnt++] = edge[i].index; 36 } 37 } 38 } 39 40 int main(){ 41 int t; 42 scanf("%d",&t); 43 while(t--){ 44 int n; 45 scanf("%d",&n); 46 for(int i = 0; i < n; i++){ 47 cin >> s[i]; 48 } 49 sort(s,s+n); 50 memset(head,-1,sizeof(head)); 51 memset(in,0,sizeof(in)); 52 memset(out,0,sizeof(out)); 53 tot = 0; 54 start = 0x3f; 55 for(int i = n-1; i >= 0; i--){//因为是邻接表头插法,所以从字典序最大的开始加 56 int len = s[i].length(); 57 int l = s[i][0] - 'a'; 58 int r = s[i][len-1] - 'a'; 59 add(l,r,i); 60 in[r]++; 61 out[l]++; 62 if(l<start) 63 start = l; 64 if(r<start) 65 start = r;//起点选择最小的 66 } 67 int q = 0, w = 0; 68 for(int i = 0; i < 30; i++){ 69 if(out[i]-in[i] == 1){ 70 q++; 71 start = i;//如果有出度>入度+1的,为起点 72 } 73 else if(in[i]-out[i] == 1) 74 w++; 75 else if(in[i]!=out[i]) 76 q=999; 77 } 78 if(!((q==0&&w==0) || (q==1&&w==1))){ 79 printf("***\n"); 80 continue; 81 } 82 cnt = 0; 83 dfs(start); 84 if(cnt!=n){ 85 printf("***\n"); 86 continue; 87 } 88 for(int i = cnt-1; i>=0; i--){ 89 cout << s[ans[i]]; 90 if(i==0) 91 printf("\n"); 92 else 93 printf("."); 94 } 95 } 96 return 0; 97 }
1 //Hdu1800 ELFhash 2 //https://www.cnblogs.com/blvt/p/7953641.html 3 #include <stdio.h> 4 #include <algorithm> 5 #include <string.h> 6 #include <math.h> 7 using namespace std; 8 9 int ans; 10 int ha[1010101],num[1010101]; 11 int mod = 1010101; 12 13 int ELFhash(char *s){ 14 unsigned int p = 0, q; 15 while(*s){ 16 p = (p << 4) + *s++;//h左移4位,当前字符占8位,再加到h中进行杂糅 17 if((q = p & 0x70000000) != 0){ //取h最左四位的值,若均为0,则括号中执行与否没区别,故不执行 18 p ^= q>>24;//用p28-31位的值对p的5~8位进行杂糅 19 p &= ~q;//清空p的最左四位 20 } 21 } 22 return p & 0x7fffffff; 23 //return p;//因为每次都清空了28~31位,最后结果最多也就是28位二进制整数,不会超int 24 } 25 26 void hash_table(char *s){ 27 int k = ELFhash(s); 28 int t = k % mod; 29 /* 30 int cnt1 = 1, cnt2 = 0; 31 while(ha[t] != k && ha[t] != -1){ 32 t = (t + cnt1*cnt1 - cnt2*cnt2)%mod; 33 cnt1++,cnt2++;//平方探测法 34 } 35 */ 36 while(ha[t] != k && ha[t] != -1){ 37 t = (t+1)%mod; 38 } 39 if(ha[t] == -1){ 40 ha[t] = k; 41 num[t] = 1; 42 }else{ 43 ans = max(ans, ++num[t]); 44 } 45 } 46 47 int main(){ 48 int n; 49 while(~scanf("%d",&n)){ 50 memset(ha,-1,sizeof(ha)); 51 memset(num,0,sizeof(num)); 52 ans = 1; 53 for(int i = 0; i < n; i++){ 54 char s[32]; 55 scanf("%s",s); 56 int k = 0; 57 while(s[k] == '0') 58 k++; 59 hash_table(s+k); 60 } 61 printf("%d\n", ans); 62 } 63 return 0; 64 }
1 //Hdu2444 二分图匹配 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 7 #define MAXN 205 8 using namespace std; 9 10 vector<int> g[MAXN]; 11 int l[MAXN]; 12 bool used[MAXN]; 13 int m, n; 14 int ans; 15 16 bool judge(int v){ 17 for(int i = 0; i < g[v].size(); i++){ 18 int z= g[v][i]; 19 if(l[z] == 0){ 20 l[z] = !l[v];//1和-1两种标记,表示属于两个集合 21 used[z] = true; 22 if(!judge(z)) 23 return false; 24 }else if(l[z] == l[v]) 25 return false; 26 } 27 return true; 28 } 29 30 bool tu(){ 31 memset(used,false,sizeof(used)); 32 memset(l,0,sizeof(l));//注意这里是0 33 for(int i = 1; i <= n; i++){ 34 if(g[i].size() && !used[i]){ 35 used[i] = true; 36 memset(l,0,sizeof(l)); 37 l[i] = 1;//第一个点标记为1 38 if(!judge(i)) 39 return false; 40 } 41 } 42 return true; 43 } 44 45 bool dfs(int v){ 46 for(int i = 0; i < g[v].size(); i++){ 47 int z = g[v][i]; 48 if(!used[z]){ 49 used[z] = true; 50 if(l[z]==-1 || dfs(l[z])){ 51 l[z] = v; 52 l[v] = z; 53 return true; 54 } 55 } 56 } 57 return false; 58 } 59 60 void solve(){ 61 memset(l,-1,sizeof(l)); 62 for(int i = 1; i <= n; i++){ 63 if(l[i]==-1){//l[i]表示i邻接l[i]边 64 memset(used,false,sizeof(used)); 65 if(dfs(i)) 66 ans++; 67 } 68 } 69 } 70 71 int main(){ 72 while(cin >> n >> m){ 73 for (int i = 0; i < MAXN; i++) 74 g[i].clear(); 75 for(int i = 0; i < m; i++){ 76 int a, b; 77 cin >> a >> b; 78 g[b].push_back(a); 79 g[a].push_back(b); 80 } 81 if(!tu())//判断是否为二分图 82 printf("No\n"); 83 else{ 84 ans = 0; 85 solve(); 86 printf("%d\n",ans); 87 } 88 } 89 return 0; 90 }
1 //Hdu2255 KM算法 2 //https://www.cnblogs.com/wenruo/p/5264235.html 3 #include <stdio.h> 4 #include <cstring> 5 #include <algorithm> 6 #define INF 0x3f3f3f3f 7 #define N 302 8 9 using namespace std; 10 11 int n; 12 int g[N][N]; 13 int exl[N], exr[N];//好感度 14 bool visl[N], visr[N];//是否被访问 15 int match[N];//match[r]=i,i是r的匹配边 16 int least[N];//r可以被匹配的最低好感度 17 18 bool dfs(int v){ 19 visl[v] = true; 20 for(int i = 0; i < n; i++){ 21 if(visr[i]) 22 continue; 23 int gg = exl[v]+exr[i]-g[v][i]; 24 if(gg == 0){ 25 visr[i] = true; 26 if(match[i]==-1 || dfs(match[i])){ 27 match[i] = v; 28 return true; 29 } 30 }else{ 31 least[i] = min(gg, least[i]); 32 } 33 } 34 return false; 35 } 36 37 int km(){ 38 memset(match, -1, sizeof(match)); 39 memset(exr, 0, sizeof(exr)); 40 41 for(int i = 0; i < n; i++){//初始好感度是最大的lr 42 exl[i] = g[i][0]; 43 for(int j = 1; j < n; j++){ 44 exl[i] = max(exl[i], g[i][j]); 45 } 46 } 47 48 for(int i = 0; i < n; i++){ 49 for(int k = 0; k < n; k++) 50 least[k] = INF;//r可以被匹配的最低好感度 51 52 while(1){//如果找不到就降低期望值,直到找到为止 53 memset(visl,false,sizeof(visl)); 54 memset(visr,false,sizeof(visr)); 55 if(dfs(i))//匹配 退出 56 break; 57 58 // 如果不能找到 就降低期望值 59 int d = INF; 60 for(int j = 0; j < n; j++){ 61 if(!visr[j]) 62 d = min(d, least[j]);// 最小可降低的期望值 63 } 64 for(int j = 0; j < n; j++){ 65 if(visl[j])//所有访问过的女生降低期望值 66 exl[j] -= d; 67 if(visr[j])//所有访问过的男生增加期望值(膨胀) 68 exr[j] += d; 69 if(!visr[j])//// 没有访问过的boy 因为girl们的期望值降低,距离得到女生倾心又进了一步! 70 least[j] -= d; 71 } 72 } 73 } 74 int ans = 0; 75 for(int h = 0; h < n; h++){ 76 ans += g[match[h]][h]; 77 } 78 return ans; 79 } 80 81 int main(){ 82 while(~scanf("%d",&n)){ 83 for(int i = 0; i < n; i++){ 84 for(int k = 0; k < n; k++) 85 scanf("%d", &g[i][k]); 86 } 87 printf("%d\n", km()); 88 } 89 return 0; 90 }
1 //Poj3020 二分图-最短路径覆盖 2 //http://blog.csdn.net/lyy289065406/article/details/6647040 3 //建图是关键,其他常规 4 //无向二分图的最小路径覆盖 = 顶点数 – 最大二分匹配数 5 #include <iostream> 6 #include <cstring> 7 #include <algorithm> 8 #include <vector> 9 #define N 402 10 using namespace std; 11 12 int cnt; 13 int tu[N][N]; 14 int used[N]; 15 vector<int> g[N]; 16 int x1[] = {0,1,-1,0}; 17 int y1[] = {1,0,0,-1}; 18 int l[N]; 19 20 bool dfs(int v){ 21 for(int i = 0; i < g[v].size(); i++){ 22 int z = g[v][i]; 23 if(!used[z]){ 24 used[z] = true; 25 if(l[z]==-1 || dfs(l[z])){ 26 l[z] = v; 27 return true; 28 } 29 } 30 } 31 return false; 32 } 33 34 int solve(){ 35 int ans = 0; 36 memset(l,-1,sizeof(l)); 37 for(int i = 1; i <= cnt; i++){ 38 memset(used,false,sizeof(used)); 39 if(dfs(i)) 40 ans++; 41 } 42 return ans/2; 43 } 44 45 int main(){ 46 int t; 47 cin >> t; 48 while(t--){ 49 cnt = 0; 50 int h,w; 51 cin >> h >> w; 52 for(int i = 0; i < N; i++) 53 g[i].clear(); 54 for(int i = 0; i < h; i++){ 55 for(int k = 0; k < w; k++){ 56 char q; 57 cin >> q; 58 if(q=='*') 59 tu[i][k] = ++cnt; 60 else 61 tu[i][k] = -1; 62 } 63 } 64 for(int i = 0; i < h; i++) 65 for(int k = 0; k < w; k++){ 66 if(tu[i][k]!=-1){ 67 for(int j = 0; j < 4; j++){ 68 int xx = i+x1[j], yy = k+y1[j]; 69 if(xx>=0 && yy>=0 && xx<h && yy<w && tu[xx][yy]!=-1){ 70 g[tu[i][k]].push_back(tu[xx][yy]); 71 } 72 } 73 } 74 } 75 cout << cnt-solve() << endl; 76 } 77 return 0; 78 }
1 //Poj3686 二分图的最佳完美匹配 2 //http://blog.csdn.net/sixdaycoder/article/details/47720471 3 #include <iostream> 4 #include <algorithm> 5 #include <cstring> 6 #include <stdio.h> 7 8 #define N 52 9 #define INF 0x3f3f3f3f 10 using namespace std; 11 12 int g[N][N]; 13 int c[N][N*N]; 14 int n, m; 15 int exl[N], exr[N*N]; 16 bool visl[N], visr[N*N]; 17 int match[N*N]; 18 int least[N*N]; 19 20 bool dfs(int v){ 21 visl[v] = true; 22 for(int i = 1; i <= m; i++){ 23 if(visr[i]) 24 continue; 25 int gg = exl[v]+exr[i]-c[v][i]; 26 if(gg==0){ 27 visr[i] = true; 28 if(match[i]==-1 || dfs(match[i])){ 29 match[i] = v; 30 return true; 31 } 32 }else 33 least[i] = min(gg,least[i]); 34 } 35 return false; 36 } 37 38 int km(){ 39 for(int i = 1; i <= n; i++){ 40 for(int j = 1; j <= m; j++){ 41 least[j] = INF; 42 } 43 while(1){ 44 memset(visl,false,sizeof(visl)); 45 memset(visr,false,sizeof(visr)); 46 if(dfs(i)){ 47 break; 48 } 49 50 int d = INF; 51 for(int j = 1; j <= m; j++){ 52 if(!visr[j]) 53 d = min(d, least[j]); 54 } 55 56 for(int j = 1; j <= n; j++) 57 if(visl[j]) 58 exl[j] -= d; 59 for(int j = 1; j <= m; j++){ 60 if(visr[j]) 61 exr[j] += d; 62 else 63 least[j] -= d; 64 } 65 } 66 } 67 int ans = 0; 68 for(int i = 1; i <= m; i++) 69 if(match[i]!=-1) 70 ans += c[match[i]][i]; 71 return ans; 72 } 73 74 75 int main(){ 76 int t; 77 cin >> t; 78 while(t--){ 79 memset(g,0,sizeof(g)); 80 memset(c,0,sizeof(c)); 81 memset(match, -1, sizeof(match)); 82 memset(exr, 0, sizeof(exr)); 83 memset(exl, 0, sizeof(exl)); 84 85 cin >> n >> m; 86 for(int i = 1; i <= n; i++) 87 for(int k = 1 ; k <= m; k++){ 88 cin>> g[i][k]; 89 } 90 91 for(int i = 1; i <= n; i++){ 92 for(int k = 1 ; k <= n; k++){ 93 for(int j = 1; j <= m; j++){ 94 c[i][(k-1)*m+j] = -g[i][j]*k; 95 } 96 } 97 } 98 m*=n; 99 printf("%.6f\n",-1.0*km()/n); 100 } 101 return 0; 102 }
1 //Poj3713 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <stdio.h> 6 #include <vector> 7 8 #define N 520 9 using namespace std; 10 11 vector<int> g[N]; 12 bool has[N], vis[N]; 13 int match[N]; 14 int n, m; 15 16 bool dfs(int u, int v){ 17 for(int i = 0; i < g[u].size(); i++){ 18 int t = g[u][i]; 19 if(t==v){ 20 if(has[u]) 21 continue; 22 has[u] = true; 23 return true; 24 } 25 if(vis[t]) 26 continue; 27 vis[t] = true; 28 if(dfs(match[t],v)){ 29 match[t] = u; 30 return true; 31 } 32 } 33 return false; 34 } 35 36 bool flow(int u,int v){ 37 memset(has,0,sizeof(has)); 38 for(int i = 0; i < n; i++){ 39 match[i] = i; 40 } 41 for(int i = 0; i < 3; i++){ 42 memset(vis,false,sizeof(vis)); 43 if(!dfs(u,v)) 44 return false; 45 } 46 return true; 47 } 48 49 bool doit(){ 50 for(int i = 1; i < n; i++){ 51 if(!flow(0,i)) 52 return false; 53 } 54 return true; 55 } 56 57 int main(){ 58 while(cin >> n >> m && n && m){ 59 for (int i = 0;i < n;++i) { 60 g[i].clear(); 61 g[i].push_back(i); 62 } 63 for(int i = 0; i < m; i++){ 64 int a, b; 65 cin >> a >> b; 66 g[a].push_back(b); 67 g[b].push_back(a); 68 } 69 if(!doit()) 70 cout << "NO" << endl; 71 else 72 cout << "YES" << endl; 73 } 74 return 0; 75 }
1 /* 2 Hdu2588 3 求k使gcd(k,n)>=m,设a = gcd(k,n) >= m 4 则 k=a*d,n=a*b(k属于1~n,d与b互质,d<b) 5 则需要枚举1-n求k,而因为k与n已知,所以a已知,相当于枚举d,因为d b互质,d<b,所以满足(k=a*d && gcd(k,n)>=m)的d的个数等于φ(b) 6 所以只枚举1-n求φ(b) 7 8 for(a = 1 to n) 9 if(n/a没有余数)//n=a*b 那么n/a就是b了 10 if(a>=m) //那么n/a就是b了 11 if(n/a>=m)//n=a*b 枚举大于根号n的一半,那么n/(n/a)就是b了 12 */ 13 #include <iostream> 14 using namespace std; 15 16 int n; 17 18 int euler(int n){ 19 int res = n; 20 for(int i = 2; i*i <= n; i++){ 21 if(n%i==0){ 22 res = res/i*(i-1); 23 while(n%i==0) 24 n/=i; 25 } 26 } 27 if(n>1) 28 res -= res/n; 29 return res; 30 } 31 32 int main(){ 33 int t; 34 cin >> t; 35 while(t--){ 36 int n, m; 37 cin >> n >> m; 38 int ans = 0; 39 for(int i = 1; i*i <= n; i++){ 40 if(n%i==0){ 41 if(i>=m) 42 ans+=euler(n/i); 43 if(n/i>=m && i*i!=n) 44 ans+=euler(i); 45 } 46 } 47 cout << ans << endl; 48 } 49 return 0; 50 }
1 //Poj3696 强行ac,不知所云 2 //https://www.cnblogs.com/chenxiwenruo/p/3569146.html 3 //a*b=c*d a与c互质时,b整除c,d整除a 4 #include <iostream> 5 #include <algorithm> 6 #include <math.h> 7 using namespace std; 8 9 typedef long long LL; 10 11 LL gcd(LL a, LL b){ 12 return b?gcd(b,a%b):a; 13 } 14 15 LL eular(LL n){ 16 LL ans = n; 17 for(LL i = 2; i*i <= n; i++){ 18 if(n%i==0){ 19 ans = ans/i*(i-1); 20 while(n%i==0) 21 n/=i; 22 } 23 } 24 if(n>1) 25 ans -= ans/n; 26 return ans; 27 } 28 29 LL mul(LL x, LL y, LL m){ 30 LL ans = 0; 31 while(y){ 32 if(y&1) 33 ans = (ans+x)%m; 34 x = x*2%m; 35 y>>=1; 36 } 37 return ans; 38 } 39 40 LL powmod(LL x, LL y, LL m){ 41 LL ans = 1; 42 while(y){ 43 if(y&1) 44 ans = mul(ans,x,m); 45 x = mul(x,x,m); 46 y>>=1; 47 } 48 return ans; 49 } 50 51 int main(){ 52 int t = 1; 53 LL L; 54 while(cin >> L){ 55 if(L == 0) break; 56 LL q = 1LL*9*L/gcd(8,L); 57 LL d = gcd(10,q); 58 if(d != 1){ 59 cout << "Case " << t++ << ": 0"<< endl; 60 }else{ 61 LL phi = eular(q); 62 LL ans = phi; 63 LL m = sqrt((double)phi); 64 bool flag = false; 65 for(LL i = 1; i <= m; i++){ 66 if(phi%i==0 && powmod(10,i,q)==1){ 67 ans = i; 68 flag = true; 69 break; 70 } 71 } 72 if(!flag){ 73 for(LL i = m; i >= 2; i--){ 74 if(phi%i==0 && powmod(10,phi/i,q)==1){ 75 ans = phi/i; 76 break; 77 } 78 } 79 } 80 cout << "Case "<< t++ << ": " << ans <<endl; 81 } 82 } 83 return 0; 84 }
1 //Poj2891 中国剩余定理/线性同余方程组(模数不一定互质情况) 2 //http://blog.csdn.net/acdreamers/article/details/8050018 3 //http://blog.csdn.net/zmh964685331/article/details/50527894 4 #include <iostream> 5 #include <algorithm> 6 #include <cstring> 7 #include <stdio.h> 8 9 using namespace std; 10 typedef long long ll; 11 ll n; 12 int m[1000002], a[1000002]; 13 14 ll exgcd(ll a, ll b, ll &x, ll &y){ 15 if(b==0){ 16 x = 1; 17 y = 0; 18 return a; 19 } 20 ll ans = exgcd(b,a%b,y,x); 21 y -= a/b*x; 22 return ans; 23 } 24 25 ll gcd(ll a, ll b){ 26 return b?gcd(b,a%b):a; 27 } 28 29 ll china(ll n){ 30 ll m1=m[0],a1=a[0],m2,a2,k1,k2,x0,mgcd,c; 31 for(int i = 1; i < n; i++){ 32 m2 = m[i], a2 = a[i]; 33 c = a2-a1; 34 mgcd=exgcd(m1,m2,k1,k2); 35 if(c%mgcd){ 36 return -1; 37 } 38 x0 = c/mgcd*k1; 39 ll t = m2/mgcd; 40 x0 = (x0%t+t)%t; 41 a1+=m1*x0; 42 m1*=m2/mgcd; 43 } 44 return a1; 45 } 46 47 int main(){ 48 while(cin >> n){ 49 for(int i = 0; i < n; i++){ 50 cin >> m[i];cin >> a[i]; 51 } 52 ll ans = china(n); 53 ll sum = 0; 54 cout << ans <<endl; 55 } 56 return 0; 57 }
1 //Hysbz1588 Splay模板 2 //模板https://files.cnblogs.com/files/tony-/Splay%E5%9F%BA%E7%A1%80_%E6%A8%A1%E6%9D%BF.pdf 3 #include <iostream> 4 #include <cmath> 5 #define l(x) ch[x][0] 6 #define r(x) ch[x][1] 7 #define N 33000 8 9 using namespace std; 10 int tot, rt; 11 int ch[N][2], pre[N], key[N], rev[N]; 12 // 儿子 父亲 节点值 翻转标记 13 14 void init(int n){ 15 rt = tot = 0; 16 l(rt)=r(rt)=pre[rt]=key[rt]=0; 17 } 18 19 void newnode(int &u, int fa, int val){ 20 u = ++tot; 21 l(u) = r(u) = 0; 22 pre[u] = fa; 23 key[u] = val; 24 } 25 26 void rotate(int u, int dir){//dir=1是右旋 27 int fa = pre[u]; 28 ch[fa][!dir] = ch[u][dir];//父亲的儿子位置更新 29 pre[ch[u][dir]] = fa;//更新原来的儿子的父亲 30 if(pre[fa])//如果父节点不是根节点,则更新爷爷的儿子 31 ch[pre[fa]][ch[pre[fa]][1]==fa]=u; 32 pre[u] = pre[fa];//更新u的父亲 33 ch[u][dir] = fa;//更新u的儿子的父亲 34 pre[fa] = u;//更新u的父亲的父亲 35 } 36 37 void splay(int u, int goal){//将节点u旋转为goal的儿子 38 int fa, kind; 39 while(pre[u] != goal){ 40 if(pre[pre[u]] == goal){//爷爷是目标,只旋转一次 41 rotate(u, l(pre[u])==u); 42 }else{ 43 fa = pre[u]; 44 int dir = l(pre[fa])==fa; 45 if(ch[fa][dir]==u){//一左一右,两次方向相反的旋转 46 rotate(u,!dir); 47 rotate(u,dir); 48 }else{//同左同右,先转父亲 49 rotate(fa,dir); 50 rotate(u,dir); 51 } 52 } 53 } 54 if(goal==0) 55 rt = u; 56 } 57 58 int insert(int val){//插入val,将此节点旋转为根 59 if(!rt) 60 newnode(rt,0,val); 61 else{ 62 int x = rt; 63 while(ch[x][key[x]<val]){//根的值小于val 64 if(key[x] == val){ 65 splay(x,0); 66 return 0; 67 } 68 x = ch[x][key[x]<val];//val>当前节点 进入右儿子,反之xxxx 69 } 70 newnode(ch[x][key[x]<val], x, val); 71 splay(ch[x][key[x]<val], 0); 72 } 73 return 1; 74 } 75 76 int getpre(int u){ 77 u = l(u); 78 while(r(u)){ 79 u=r(u); 80 } 81 return u; 82 } 83 84 int getnxt(int u){ 85 u = r(u); 86 while(l(u)){ 87 u=l(u); 88 } 89 return u; 90 } 91 92 int main(){ 93 int a; 94 int n; 95 cin >> n; 96 init(n); 97 insert(-0x3f3f3f3f);//插入两个无限大小的点,才可以比较大小 98 insert(0x3f3f3f3f); 99 cin >> a; 100 insert(a); 101 int sum = a; 102 for(int i = 1; i < n; i++){ 103 cin >> a; 104 if(insert(a)) 105 sum += min(a-key[getpre(rt)], key[getnxt(rt)]-a);//a已经转为根,直接找rt的pre和next 106 //cout<<"i="<<i <<" "<<sum <<" "<<key[getpre(rt)]<<" "<<key[getnxt(rt)]<<endl; 107 } 108 cout << sum <<endl; 109 return 0; 110 }
1 //Hdu1754 splay单点修改,区间查询 2 //https://files.cnblogs.com/files/tony-/Splay%E5%9F%BA%E7%A1%80_%E6%A8%A1%E6%9D%BF.pdf 3 #include <iostream> 4 #include <stdio.h> 5 #include <algorithm> 6 #include <cstring> 7 #define l(x) ch[x][0] 8 #define r(x) ch[x][1] 9 using namespace std; 10 11 #define INF 0x3f3f3f3f 12 #define ll long long 13 #define l(x) ch[x][0] 14 #define r(x) ch[x][1] 15 #define keytree ch[ch[rt][1]][0] 16 #define N 200010 17 18 int rt, tot; 19 int key[N],ch[N][2], pre[N], p[N], cnt[N], maxi[N], siz[N]; 20 // 结点的值 儿子 父亲 数组的值 本结点规模 子树最大值 包含自身的子树大小 21 22 void inline push_up(int u){ 23 siz[u] = siz[l(u)] + siz[r(u)] + cnt[u]; 24 maxi[u] = max(max(maxi[l(u)],maxi[r(u)]), key[u]); 25 } 26 27 int inline getkth(int u, int k){ 28 int s = siz[l(u)]; 29 if(s==k) 30 return u; 31 if(s>k) 32 return getkth(l(u), k); 33 return getkth(r(u), k-s-1); 34 } 35 36 void inline rotate(int u, int dir){//dir=1是右旋 37 int fa = pre[u]; 38 ch[fa][!dir] = ch[u][dir]; 39 pre[ch[u][dir]] = fa; 40 if(pre[fa]){ 41 int son = ch[pre[fa]][1]==fa; 42 ch[pre[fa]][son] = u; 43 } 44 pre[u] = pre[fa]; 45 ch[u][dir] = fa; 46 pre[fa] = u; 47 push_up(fa); 48 } 49 50 void inline splay(int u, int goal){//将节点u旋转为goal的儿子 51 while(pre[u] != goal){ 52 if(pre[pre[u]] == goal){//爷爷是目标,只旋转一次 53 rotate(u, l(pre[u])==u); 54 }else{ 55 int fa, dir; 56 fa = pre[u]; 57 dir = l(pre[fa]) == fa;//左儿子1,右儿子0 58 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 59 rotate(u, !dir); 60 rotate(u,dir); 61 }else{//同左同右,先转父亲 62 rotate(fa, dir); 63 rotate(u, dir); 64 } 65 } 66 } 67 push_up(u); 68 if(goal == 0) 69 rt = u; 70 } 71 72 int inline query(int l, int r){ 73 splay(getkth(rt,l-1), 0); 74 splay(getkth(rt,r+1), rt); 75 return maxi[keytree]; 76 } 77 78 void inline update(int k,int val){ 79 int u = getkth(rt, k); 80 splay(u, 0); 81 key[u] = val; 82 push_up(u); 83 } 84 85 void inline newnode(int &u, int fa, int val){ 86 u = ++tot; 87 l(u) = r(u) = 0; 88 pre[u] = fa; 89 siz[u] = cnt[u] = 1; 90 key[u] = maxi[u] = val; 91 } 92 93 void inline build(int &u, int l, int r, int fa){ 94 if(l>r) 95 return; 96 int mid = (l+r)>>1; 97 newnode(u, fa, p[mid]); 98 build(l(u), l, mid-1, u); 99 build(r(u), mid+1, r, u); 100 push_up(u); 101 } 102 103 void inline init(int n){ 104 rt = tot = 0; 105 l(rt) = r(rt) = pre[rt] = siz[rt] = cnt[rt] = 0; 106 key[rt] = maxi[rt] = -1; 107 newnode(rt,0,-1);//插入两个虚点 108 newnode(r(rt),rt,-1); 109 build(keytree, 1, n, r(rt)); 110 push_up(r(rt)); 111 push_up(rt); 112 } 113 114 int main() { 115 int n, m; 116 while(~scanf("%d%d", &n, &m)){ 117 for(int i = 1; i <= n; i++) 118 scanf("%d",&p[i]); 119 init(n); 120 char sh[2]; 121 while(m--){ 122 scanf("%s",sh); 123 if(sh[0]=='Q'){ 124 int l, r; 125 scanf("%d%d",&l, &r); 126 cout << query(l, r) << endl; 127 }else{ 128 int k, val; 129 scanf("%d%d",&k, &val); 130 update(k, val); 131 } 132 } 133 } 134 return 0; 135 }
1 //Poj3468 区间修改,区间查询 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 #define l(x) ch[x][0] 7 #define r(x) ch[x][1] 8 using namespace std; 9 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 #define l(x) ch[x][0] 13 #define r(x) ch[x][1] 14 #define keytree ch[ch[rt][1]][0] 15 #define N 100010 16 17 int rt, tot; 18 ll sum[N];//延迟更新 子树结点和 19 int add[N], key[N], ch[N][2], pre[N], p[N], siz[N]; 20 // 要更新的值 结点的值 儿子 父亲 数组的值 本结点规模 21 22 void inline push_up(int u){ 23 siz[u] = siz[l(u)] + siz[r(u)] + 1; 24 sum[u] = sum[l(u)] + sum[r(u)] + key[u] + add[u]; 25 } 26 27 void push_down(int u){ 28 if(add[u]){//将延迟标记更新到孩子结点 29 key[u] += add[u]; 30 add[l(u)] += add[u]; 31 add[r(u)] += add[u]; 32 sum[l(u)] += 1ll*add[u]*siz[l(u)]; 33 sum[r(u)] += 1ll*add[u]*siz[r(u)]; 34 add[u] = 0; 35 } 36 } 37 38 int inline getkth(int u, int k){//获取第k位,u是根 39 push_down(u); 40 int s = siz[l(u)]; 41 if(s==k) 42 return u; 43 if(s>k) 44 return getkth(l(u), k); 45 return getkth(r(u), k-s-1); 46 } 47 48 void inline rotate(int u, int dir){//dir=1是右旋 49 int fa = pre[u]; 50 ch[fa][!dir] = ch[u][dir]; 51 pre[ch[u][dir]] = fa; 52 if(pre[fa]){ 53 int son = ch[pre[fa]][1]==fa; 54 ch[pre[fa]][son] = u; 55 } 56 pre[u] = pre[fa]; 57 ch[u][dir] = fa; 58 pre[fa] = u; 59 push_up(fa); 60 } 61 62 void inline splay(int u, int goal){//将节点u旋转为goal的儿子 63 push_down(u); 64 while(pre[u] != goal){ 65 int fa, dir; 66 fa = pre[u]; 67 if(pre[fa] == goal){//爷爷是目标,只旋转一次 68 push_down(fa); 69 push_down(u); 70 rotate(u, l(fa)==u); 71 }else{ 72 push_down(pre[fa]); 73 push_down(fa); 74 push_down(u); 75 dir = l(pre[fa])==fa;//左儿子1,右儿子0 76 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 77 rotate(u, !dir); 78 rotate(u,dir); 79 }else{//同左同右,先转父亲 80 rotate(fa, dir); 81 rotate(u, dir); 82 } 83 } 84 } 85 push_up(u); 86 if(goal == 0) 87 rt = u; 88 } 89 90 ll inline query(int l, int r){ 91 splay(getkth(rt,l-1), 0); 92 splay(getkth(rt,r+1), rt); 93 return sum[keytree]; 94 } 95 96 void inline update(int l, int r,int val){ 97 splay(getkth(rt,l-1), 0); 98 splay(getkth(rt,r+1), rt); 99 add[keytree] += val; 100 sum[keytree] += siz[keytree]*val; 101 } 102 103 void inline newnode(int &u, int fa, int val){ 104 u = ++tot; 105 l(u) = r(u) = 0; 106 pre[u] = fa; 107 siz[u] = 1; 108 key[u] = sum[u] = val; 109 add[u] = 0; 110 } 111 112 void inline build(int &u, int l, int r, int fa){ 113 if(l>r)//建树 中间结点先建立 然后分别对区间两端在左右子树建立 114 return; 115 int mid = (l+r)>>1; 116 newnode(u, fa, p[mid]); 117 build(l(u), l, mid-1, u); 118 build(r(u), mid+1, r, u); 119 push_up(u); 120 } 121 122 void inline init(int n){ 123 rt = tot = 0; 124 l(rt) = r(rt) = pre[rt] = siz[rt] = 0; 125 add[rt] = sum[rt] = 0; 126 newnode(rt, 0, -1);//插入两个虚点 127 newnode(r(rt), rt, -1); 128 siz[rt] = 2; 129 } 130 131 int main() { 132 int n, m; 133 while(~scanf("%d%d", &n, &m)){ 134 for(int i = 1; i <= n; i++) 135 scanf("%d",&p[i]); 136 init(n); 137 build(keytree, 1, n, r(rt)); 138 push_up(r(rt)); 139 push_up(rt); 140 char sh[2]; 141 while(m--){ 142 scanf("%s",sh); 143 int l, r, val; 144 if(sh[0]=='Q'){ 145 scanf("%d%d",&l, &r); 146 cout << query(l, r) << endl; 147 }else{ 148 scanf("%d%d%d", &l, &r, &val); 149 update(l, r, val); 150 } 151 } 152 } 153 return 0; 154 }
1 //Hdu1890 splay区间翻转 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 #define l(x) ch[x][0] 7 #define r(x) ch[x][1] 8 using namespace std; 9 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 #define l(x) ch[x][0] 13 #define r(x) ch[x][1] 14 #define keytree ch[ch[rt][1]][0] 15 #define N 100010 16 17 struct g{ 18 int num, id; 19 bool operator < (const g c) const{ 20 if(num==c.num) return id<c.id; 21 return num < c.num; 22 } 23 }p[N]; 24 25 int rt, tot, id[N], mini[N];//子树的最小值 26 int key[N], ch[N][2], pre[N], siz[N], flip[N]; 27 // 结点的值 儿子 父亲 本结点规模 是否翻转 28 29 void inline push_up(int u){ 30 siz[u] = siz[l(u)] + siz[r(u)] + 1; 31 mini[u] = min(key[u], min(mini[l(u)], mini[r(u)])); 32 } 33 34 void push_down(int u){//延迟更新,翻转 35 if(flip[u]){ 36 if(l(u)) 37 flip[l(u)] ^= 1; 38 if(r(u)) 39 flip[r(u)] ^= 1; 40 swap(l(u), r(u)); 41 flip[u] = 0; 42 } 43 } 44 45 int inline getkth(int u, int k){//获取第k位,u是根 46 push_down(u); 47 int s = siz[l(u)] + 1; 48 if(s==k) 49 return u; 50 if(s>k) 51 return getkth(l(u), k); 52 return getkth(r(u), k-s); 53 } 54 55 void inline rotate(int u, int dir){//dir=1是右旋 56 int fa = pre[u]; 57 ch[fa][!dir] = ch[u][dir]; 58 pre[ch[u][dir]] = fa; 59 if(pre[fa]){ 60 int son = ch[pre[fa]][1]==fa; 61 ch[pre[fa]][son] = u; 62 } 63 pre[u] = pre[fa]; 64 ch[u][dir] = fa; 65 pre[fa] = u; 66 push_up(fa); 67 } 68 69 void inline splay(int u, int goal){//将节点u旋转为goal的儿子 70 push_down(u); 71 while(pre[u] != goal){ 72 int fa, dir; 73 fa = pre[u]; 74 if(pre[fa] == goal){//爷爷是目标,只旋转一次 75 push_down(fa); 76 push_down(u); 77 rotate(u, l(fa)==u); 78 }else{ 79 push_down(pre[fa]); 80 push_down(fa); 81 push_down(u); 82 dir = l(pre[fa])==fa;//左儿子1,右儿子0 83 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 84 rotate(u, !dir); 85 rotate(u,dir); 86 }else{//同左同右,先转父亲 87 rotate(fa, dir); 88 rotate(u, dir); 89 } 90 } 91 } 92 push_up(u); 93 if(goal == 0) 94 rt = u; 95 } 96 97 int getpre(int u){//求u的前驱 98 push_down(u); 99 u = l(u); 100 push_down(u); 101 while(r(u)){ 102 u = r(u); 103 push_down(u); 104 } 105 return u; 106 } 107 108 void del(int u){//旋转到根然后删去 109 splay(getkth(rt, u), 0); 110 if(l(rt)){ 111 int i = getpre(rt); 112 splay(i, rt); 113 r(i) = r(rt); 114 pre[r(rt)] = i; 115 rt = l(rt); 116 pre[rt] = 0; 117 push_up(rt); 118 }else{ 119 rt = r(rt); 120 pre[rt] = 0; 121 } 122 } 123 124 void inline newnode(int &u, int fa, int val){ 125 u = ++tot; 126 l(u) = r(u) = 0; 127 pre[u] = fa; 128 siz[u] = 1; 129 mini[u] = key[u] = val; 130 flip[u] = 0; 131 } 132 133 void inline build(int &u, int l, int r, int fa){ 134 if(l>r)//建树 中间结点先建立 然后分别对区间两端在左右子树建立 135 return; 136 int mid = (l+r)>>1; 137 newnode(u, fa, id[mid]); 138 build(l(u), l, mid-1, u); 139 build(r(u), mid+1, r, u); 140 push_up(u); 141 } 142 143 void inline init(int n){ 144 rt = tot = 0; 145 l(rt) = r(rt) = pre[rt] = siz[rt] = flip[rt] = 0; 146 key[rt] = mini[rt] = N; 147 newnode(rt, 0, INF);//插入两个虚点 148 newnode(r(rt), rt, INF); 149 build(keytree, 1, n, r(rt)); 150 push_up(r(rt)); 151 push_up(rt); 152 } 153 154 int getmin(int u, int x){//求子树的最小值 155 push_down(u); 156 if(key[u] == x) 157 return 1 + siz[l(u)]; 158 if(mini[l(u)] == x) 159 return getmin(l(u),x); 160 if(mini[r(u)] == x) 161 return siz[l(u)]+getmin(r(u),x)+1; 162 } 163 164 int main() { 165 int n; 166 while(~scanf("%d", &n) && n){ 167 for(int i = 1; i <= n; i++){ 168 scanf("%d",&p[i].num); 169 p[i].id = i; 170 } 171 sort(p+1, p+n+1); 172 for(int i = 1; i <= n; i++) 173 id[p[i].id] = i;//重新做个标记 174 init(n); 175 for(int i = 1; i < n; i++){ 176 int ans = getmin(rt, i);//找到值i的位置 177 cout << ans+i-2; 178 if(i<n) 179 cout << " "; 180 splay(getkth(rt,1), 0); 181 splay(getkth(rt,ans), rt); 182 flip[keytree] ^= 1; 183 del(ans); 184 }cout << n << endl; 185 } 186 return 0; 187 }
1 //Hysbz1269 splay区间旋转 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 #define l(x) ch[x][0] 7 #define r(x) ch[x][1] 8 using namespace std; 9 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 #define l(x) ch[x][0] 13 #define r(x) ch[x][1] 14 #define keytree ch[ch[rt][1]][0] 15 #define N 2*1024*1024+2 16 17 char sh[N]; 18 int pos; 19 int rt, tot; 20 int key[N], ch[N][2], pre[N], siz[N], flip[N]; 21 // 结点的值 儿子 父亲 本结点规模 是否翻转 22 23 void visit(int u){//for test 24 if(!u) return; 25 visit(l(u)); 26 printf("u:%d lch:%d rch:%d key:%c pos:%d\n",u,l(u),r(u),key[u],pos); 27 visit(r(u)); 28 } 29 30 void push_up(int u){ 31 siz[u] = siz[l(u)] + siz[r(u)] + 1; 32 } 33 34 void push_down(int u){//延迟更新,翻转 35 if(flip[u]){ 36 flip[l(u)] ^= 1; 37 flip[r(u)] ^= 1; 38 swap(l(u), r(u)); 39 flip[u] = 0; 40 } 41 } 42 43 void rotate(int u, int dir){//dir=1是右旋 44 int fa = pre[u]; 45 ch[fa][!dir] = ch[u][dir]; 46 pre[ch[u][dir]] = fa; 47 if(pre[fa]){ 48 int son = ch[pre[fa]][1]==fa; 49 ch[pre[fa]][son] = u; 50 } 51 pre[u] = pre[fa]; 52 ch[u][dir] = fa; 53 pre[fa] = u; 54 push_up(fa); 55 } 56 57 void splay(int u, int goal){//将节点u旋转为goal的儿子 58 push_down(u); 59 while(pre[u] != goal){ 60 int fa, dir; 61 fa = pre[u]; 62 if(pre[fa] == goal){//爷爷是目标,只旋转一次 63 push_down(fa); 64 push_down(u); 65 rotate(u, l(fa)==u); 66 }else{ 67 push_down(pre[fa]); 68 push_down(fa); 69 push_down(u); 70 dir = l(pre[fa])==fa;//左儿子1,右儿子0 71 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 72 rotate(u, !dir); 73 rotate(u,dir); 74 }else{//同左同右,先转父亲 75 rotate(fa, dir); 76 rotate(u, dir); 77 } 78 } 79 } 80 push_up(u); 81 if(goal == 0) 82 rt = u; 83 } 84 85 int getkth(int u, int t){//获取第t位,u是根 86 push_down(u); 87 int s = siz[l(u)]; 88 if(s==t) 89 return u; 90 if(s>t) 91 return getkth(l(u),t); 92 return getkth(r(u), t-s-1); 93 } 94 95 void insert(int u, int x){//插入x到k尾部 96 splay(getkth(rt,u), 0); 97 splay(getkth(rt,u+1), rt); 98 pre[x] = r(rt); 99 keytree = x; 100 push_up(r(rt)); 101 push_up(rt); 102 } 103 104 void newnode(int &u, int fa, int val){ 105 u = ++tot; 106 l(u) = r(u) = 0; 107 pre[u] = fa; 108 siz[u] = 1; 109 flip[u] = 0; 110 key[u] = val; 111 } 112 113 void build(int &u, int l, int r, int fa){ 114 if(l > r) return; 115 int mid = (l+r)>>1; 116 newnode(u,fa,(int)sh[mid]); 117 build(l(u),l,mid-1,u); 118 build(r(u),mid+1,r,u); 119 push_up(u); 120 } 121 122 void init(){ 123 rt = tot = 0; 124 key[rt] = l(rt) = r(rt) = pre[rt] = siz[rt] = flip[rt] = 0; 125 newnode(rt, 0, -1);//插入两个虚点 126 newnode(r(rt), rt, -1); 127 push_up(r(rt)); 128 push_up(rt); 129 } 130 131 void del(int u, int p){ 132 splay(getkth(rt,u), 0); 133 splay(getkth(rt,u+p+1), rt); 134 keytree = 0; 135 push_up(r(rt)); 136 push_up(rt); 137 } 138 139 void flipp(int u, int p){ 140 splay(getkth(rt, u), 0); 141 splay(getkth(rt, u+p+1), rt); 142 flip[keytree] ^= 1; 143 } 144 145 int got(int p){ 146 splay(getkth(rt, p+1), 0); 147 return key[rt]; 148 } 149 150 int main() { 151 int t; 152 scanf("%d",&t); 153 pos = 0;//初始光标位置 154 init(); 155 while(t--){ 156 char q[20]; 157 scanf("%s",q); 158 int n; 159 if(q[0]=='M'){//move 160 scanf("%d",&pos); 161 }else if(q[0]=='I'){//insert 162 scanf("%d",&n); 163 getchar(); 164 gets(sh); 165 int newrt = 0; 166 build(newrt, 0, n-1, 0); 167 insert(pos, newrt); 168 }else if(q[0]=='D'){//delete 169 scanf("%d",&n); 170 del(pos,n); 171 }else if(q[0]=='R'){//rotate 172 scanf("%d",&n); 173 flipp(pos, n); 174 }else if(q[0]=='G'){//get 175 printf("!!!!!!!%c!!!!!!!!\n", got(pos)); 176 }else if(q[0]=='P'){//prev 177 pos--; 178 }else if(q[0]=='N'){//next 179 pos++; 180 } 181 //visit(rt); 182 } 183 return 0; 184 }
1 //Hysbz3223 splay区间翻转 裸 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 #define l(x) ch[x][0] 7 #define r(x) ch[x][1] 8 using namespace std; 9 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 #define l(x) ch[x][0] 13 #define r(x) ch[x][1] 14 #define keytree ch[ch[rt][1]][0] 15 #define N 100010 16 17 int rt, tot, id[N];//子树的最小值 18 int key[N], ch[N][2], pre[N], siz[N], flip[N]; 19 // 结点的值 儿子 父亲 本结点规模 是否翻转 20 21 void inline push_up(int u){ 22 siz[u] = siz[l(u)] + siz[r(u)] + 1; 23 } 24 25 void push_down(int u){//延迟更新,翻转 26 if(flip[u]){ 27 flip[l(u)] ^= 1; 28 flip[r(u)] ^= 1; 29 swap(l(u), r(u)); 30 flip[u] = 0; 31 } 32 } 33 34 int inline getkth(int u, int k){//获取第k位,u是根 35 push_down(u); 36 int s = siz[l(u)]; 37 if(s==k) 38 return u; 39 if(s>k) 40 return getkth(l(u), k); 41 return getkth(r(u), k-s-1); 42 } 43 44 void inline rotate(int u, int dir){//dir=1是右旋 45 int fa = pre[u]; 46 ch[fa][!dir] = ch[u][dir]; 47 pre[ch[u][dir]] = fa; 48 if(pre[fa]){ 49 int son = ch[pre[fa]][1]==fa; 50 ch[pre[fa]][son] = u; 51 } 52 pre[u] = pre[fa]; 53 ch[u][dir] = fa; 54 pre[fa] = u; 55 push_up(fa); 56 } 57 58 void inline splay(int u, int goal){//将节点u旋转为goal的儿子 59 push_down(u); 60 while(pre[u] != goal){ 61 int fa, dir; 62 fa = pre[u]; 63 if(pre[fa] == goal){//爷爷是目标,只旋转一次 64 push_down(fa); 65 push_down(u); 66 rotate(u, l(fa)==u); 67 }else{ 68 push_down(pre[fa]); 69 push_down(fa); 70 push_down(u); 71 dir = l(pre[fa])==fa;//左儿子1,右儿子0 72 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 73 rotate(u, !dir); 74 rotate(u,dir); 75 }else{//同左同右,先转父亲 76 rotate(fa, dir); 77 rotate(u, dir); 78 } 79 } 80 } 81 push_up(u); 82 if(goal == 0) 83 rt = u; 84 } 85 86 void inline newnode(int &u, int fa, int val){ 87 u = ++tot; 88 l(u) = r(u) = 0; 89 pre[u] = fa; 90 siz[u] = 1; 91 key[u] = val; 92 flip[u] = 0; 93 } 94 95 void inline build(int &u, int l, int r, int fa){ 96 if(l>r)//建树 中间结点先建立 然后分别对区间两端在左右子树建立 97 return; 98 int mid = (l+r)>>1; 99 newnode(u, fa, id[mid]); 100 build(l(u), l, mid-1, u); 101 build(r(u), mid+1, r, u); 102 push_up(u); 103 } 104 105 void init(int n){ 106 rt = tot = 0; 107 l(rt) = r(rt) = pre[rt] = siz[rt] = flip[rt] = 0; 108 key[rt] = N; 109 newnode(rt, 0, INF);//插入两个虚点 110 newnode(r(rt), rt, INF); 111 build(keytree, 1, n, r(rt)); 112 push_up(r(rt)); 113 push_up(rt); 114 } 115 116 void out(int x){ 117 if(!x) return; 118 push_down(x); 119 out(l(x)); 120 if(key[x]!=INF) 121 printf("%d ",key[x]); 122 out(r(x)); 123 } 124 125 int main() { 126 int n, m; 127 scanf("%d%d", &n, &m); 128 for(int i = 1; i <= n; i++) 129 id[i] = i; 130 init(n); 131 132 for(int i = 0; i < m; i++){ 133 int l, r; 134 scanf("%d%d", &l, &r); 135 splay(getkth(rt,l-1),0); 136 splay(getkth(rt,r+1),rt); 137 flip[keytree] ^= 1; 138 //cout<< rt<<" "<<id[rt]<<endl; 139 } 140 out(rt); 141 return 0; 142 }
1 //Hysbz3224 splay 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 #define l(x) ch[x][0] 7 #define r(x) ch[x][1] 8 using namespace std; 9 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 #define l(x) ch[x][0] 13 #define r(x) ch[x][1] 14 #define keytree ch[ch[rt][1]][0] 15 #define N 100002 16 17 int rt, tot; 18 int key[N], ch[N][2], pre[N], siz[N], cnt[N]; 19 // 结点的值 儿子 父亲 本结点规模 20 21 void visit(int u){//for test 22 if(!u) return; 23 visit(l(u)); 24 printf("u:%d lch:%d rch:%d key:%c\n",u,l(u),r(u),key[u]); 25 visit(r(u)); 26 } 27 28 int getpre(int u){ 29 u = l(u); 30 while(r(u)){ 31 u=r(u); 32 } 33 return u; 34 } 35 36 int getnxt(int u){ 37 u = r(u); 38 while(l(u)){ 39 u=l(u); 40 } 41 return u; 42 } 43 44 void push_up(int u){ 45 siz[u] = siz[l(u)] + siz[r(u)] + cnt[u]; 46 } 47 48 void rotate(int u, int dir){//dir=1是右旋 49 int fa = pre[u]; 50 ch[fa][!dir] = ch[u][dir]; 51 pre[ch[u][dir]] = fa; 52 if(pre[fa]){ 53 int son = ch[pre[fa]][1]==fa; 54 ch[pre[fa]][son] = u; 55 } 56 pre[u] = pre[fa]; 57 ch[u][dir] = fa; 58 pre[fa] = u; 59 push_up(fa); 60 } 61 62 void inline splay(int u, int goal){//将节点u旋转为goal的儿子 63 while(pre[u] != goal){ 64 if(pre[pre[u]] == goal){//爷爷是目标,只旋转一次 65 rotate(u, l(pre[u])==u); 66 }else{ 67 int fa, dir; 68 fa = pre[u]; 69 dir = l(pre[fa]) == fa;//左儿子1,右儿子0 70 if(ch[fa][dir] == u){//一左一右,两次方向相反的旋转 71 rotate(u, !dir); 72 rotate(u,dir); 73 }else{//同左同右,先转父亲 74 rotate(fa, dir); 75 rotate(u, dir); 76 } 77 } 78 } 79 push_up(u); 80 if(goal == 0) 81 rt = u; 82 } 83 84 void newnode(int &u, int fa, int val){ 85 u = ++tot; 86 l(u) = r(u) = 0; 87 pre[u] = fa; 88 siz[u] = cnt[u] = 1; 89 key[u] = val; 90 } 91 92 void insert(int val){//插入val,将此节点旋转为根 93 if(!rt) 94 newnode(rt,0,val); 95 else{ 96 int x = rt, fa = 0; 97 while(x){ 98 if(key[x] == val){ 99 cnt[x]++; 100 push_up(x); 101 push_up(fa); 102 splay(x,0); 103 return; 104 } 105 fa = x; 106 x = ch[x][key[x]<val];//val>当前节点 进入右儿子,反之xxxx 107 } 108 newnode(x, fa, val);//没有此结点 109 ch[fa][key[fa]<val] = x; 110 push_up(fa); 111 splay(x, 0); 112 } 113 } 114 115 int find(int x){//查询x的排名 116 int nowrt = rt, ans = 0; 117 while(1){ 118 if(x < key[nowrt]) 119 nowrt = l(nowrt); 120 else{ 121 ans += l(nowrt)?siz[l(nowrt)]:0; 122 if(x == key[nowrt]){ 123 splay(nowrt, 0); 124 return ans + 1; 125 } 126 ans += cnt[nowrt]; 127 nowrt = r(nowrt); 128 } 129 } 130 } 131 132 int findx(int x){//排名为x的数 133 int nowrt = rt; 134 while(1){ 135 if(l(nowrt) && x<=siz[l(nowrt)]){ 136 nowrt = l(nowrt); 137 }else{ 138 int ans = l(nowrt)?siz[l(nowrt)]:0; 139 ans += cnt[nowrt]; 140 if(x <= ans) 141 return key[nowrt]; 142 x -= ans; 143 nowrt = r(nowrt); 144 } 145 } 146 } 147 148 void clear(int x){ 149 l(x) = r(x) = pre[x] = siz[x] = cnt[x] = 0; 150 } 151 152 void del(int x){//cnt==1 考虑有无左右儿子的情况 153 find(x); 154 if(cnt[rt] > 1){//cnt>1 155 cnt[rt]--; 156 return ; 157 } 158 if(!l(rt) && ! r(rt)){ 159 clear(rt); 160 rt = 0; 161 return; 162 } 163 if(!l(rt)){ 164 int oldrt = rt; 165 rt = r(rt); 166 pre[rt] = 0; 167 clear(oldrt); 168 return; 169 }else if(!r(rt)){ 170 int oldrt = rt; 171 rt = l(rt); 172 pre[rt] = 0; 173 clear(oldrt); 174 return; 175 } 176 int oldrt = rt; 177 splay(getpre(rt),0); 178 pre[r(oldrt)] = rt; 179 r(rt) = r(oldrt); 180 clear(oldrt); 181 push_up(rt); 182 } 183 184 int main() { 185 int t; 186 scanf("%d",&t); 187 while(t--){ 188 int k, n; 189 scanf("%d",&k); 190 scanf("%d",&n); 191 if(k==1){//insert 192 insert(n); 193 }else if(k==2){//delete 194 del(n); 195 }else if(k==3){//query 196 printf("%d\n", find(n)); 197 }else if(k==4){//query rank==n 198 printf("%d\n", findx(n)); 199 }else if(k==5){//prev 200 insert(n); 201 printf("%d\n", key[getpre(rt)]); 202 del(n); 203 }else if(k==6){//next 204 insert(n); 205 printf("%d\n", key[getnxt(rt)]); 206 del(n); 207 } 208 //visit(rt); 209 } 210 return 0; 211 }
1 //最小边覆盖 2 #include <stdio.h> 3 #include <iostream> 4 #include <cstring> 5 #include <string.h> 6 #include <stdlib.h> 7 using namespace std; 8 9 int o; 10 char g[50][50]; 11 int edge[50][50]; 12 int a[50][50]; 13 int gg[50]; 14 int vis[50]; 15 int n ,m; 16 int cnt, ans; 17 int xn[] = {0,1,0,-1}; 18 int yn[] = {1,0,-1,0}; 19 20 void dfs(int x, int y){//cout << "now="<<x << " "<<y<<endl; 21 if(g[x][y] == '*'){ 22 for(int i = 0; i < 4; i++){ 23 int x1 = x+xn[i], y1 = y+yn[i]; 24 if(x1>=0 && x1<n && y1>=0 && y1<m && g[x1][y1]=='*'){ 25 edge[a[x][y]][a[x1][y1]] = 1; 26 } 27 } 28 } 29 } 30 31 int path(int u) 32 { 33 int v; 34 for(v=0; v<o; v++) 35 { 36 if(edge[u][v]&&!vis[v]) 37 { 38 vis[v]=1; 39 if(gg[v]==-1||path(gg[v])) 40 { 41 gg[v]=u; 42 return 1; 43 } 44 } 45 } 46 return 0; 47 } 48 49 int main(){ 50 int t; 51 scanf("%d",&t); 52 while(t--){ 53 ans = 1; 54 scanf("%d%d",&n,&m); 55 for(int i = 0; i < n; i++){ 56 for(int j = 0; j < m; j++){ 57 scanf(" %c",&g[i][j]); 58 if(g[i][j]=='*') 59 a[i][j] = ans++; 60 } 61 } 62 o = ans; 63 memset(edge,0,sizeof(edge)); 64 for(int i = 0; i < n; i++){ 65 for(int j = 0; j < m; j++){ 66 dfs(i,j); 67 } 68 } 69 int cnt = 0; 70 memset(gg,-1,sizeof(gg)); 71 for(int i=0; i<o; i++) 72 { 73 memset(vis,0,sizeof(vis)); 74 cnt+=path(i); 75 } 76 cout << ans-1-cnt/2 << endl; 77 } 78 return 0; 79 }
1 //莫队算法 2 #include <iostream> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cstring> 6 using namespace std; 7 8 int got[200010],sum[30010],ch[30010]; 9 int ans; 10 struct stu{ 11 int l,r,p; 12 }node[200010]; 13 14 int cmp(stu a, stu b){ 15 return a.l==b.l ? a.r<b.r : a.l<b.l; 16 } 17 18 void add(int x){ 19 if(!got[x]) 20 ans++; 21 got[x]++; 22 } 23 24 void del(int x){ 25 got[x]--; 26 if(!got[x]) 27 ans--; 28 } 29 30 int main() 31 { 32 int n; 33 while(~scanf("%d",&n)){ 34 for(int i = 1; i <= n; i++){ 35 scanf("%d",&ch[i]); 36 } 37 int m; 38 scanf("%d",&m); 39 for(int i = 1; i <= m; i++){ 40 scanf("%d%d",&node[i].l,&node[i].r); 41 node[i].p = i; 42 } 43 sort(node,node+m,cmp); 44 45 ans = 0; 46 int l = 1, r = 0; 47 memset(got,0,sizeof(got)); 48 for(int i = 1; i <= m; i++){ 49 while(r < node[i].r) 50 add(ch[++r]); 51 52 while(l > node[i].l) 53 add(ch[--l]); 54 55 while(r > node[i].r) 56 del(ch[r--]); 57 58 while(l < node[i].l) 59 del(ch[l++]); 60 61 sum[node[i].p] = ans; 62 } 63 for(int i = 1; i <= m; i++){ 64 printf("%d\n", sum[i]); 65 } 66 67 } 68 return 0; 69 }
One day one AC.

浙公网安备 33010602011771号