zoukankan      html  css  js  c++  java
  • 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] = '';
    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 }
    Gdufe-OJ1459
     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 }
    Hdu3923
     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 }
    Poj3070
     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("
    ");
    61         }
    62     }
    63     return 0;
    64 }
    Poj3233
     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("
    ");
    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 }
    Hdu2276
     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 }
    Hdu3018
     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
    ", 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 }
    Poj2230
     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 }
    Poj1386
     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("***
    ");
    80             continue;
    81         }
    82         cnt = 0;
    83         dfs(start);
    84         if(cnt!=n){
    85             printf("***
    ");
    86             continue;
    87         }
    88         for(int i = cnt-1; i>=0; i--){
    89             cout << s[ans[i]];
    90             if(i==0)
    91                 printf("
    ");
    92             else
    93                 printf(".");
    94         }
    95     }
    96     return 0;
    97 }
    Poj2337
     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
    ", ans);
    62     }
    63     return 0;
    64 }
    Hdu1800
     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
    "); 
    83         else{
    84             ans = 0;
    85             solve();
    86             printf("%d
    ",ans);   
    87         }
    88     }
    89     return 0;
    90 }
    Hdu2444
     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
    ", km());
    88     }
    89     return 0;
    90 }
    Hdu2255
     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 }
    Poj3020
      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
    ",-1.0*km()/n);
    100     }
    101     return 0;
    102 }
    Poj3686
     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 }
    Poj3713
     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 }
    Hdu2588
     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 }
    Poj3696
     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 }
    Poj2891
      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 }
    Hysbz1588
      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 }
    Hdu1754
      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 }
    Poj3468
      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 }
    Hdu1890
      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
    ",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!!!!!!!!
    ", 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 }
    Hysbz1269
      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 }
    Hysbz3223
      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
    ",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
    ", find(n));
    197         }else if(k==4){//query rank==n
    198             printf("%d
    ", findx(n));
    199         }else if(k==5){//prev
    200             insert(n);
    201             printf("%d
    ", key[getpre(rt)]);
    202             del(n);
    203         }else if(k==6){//next
    204             insert(n);
    205             printf("%d
    ", key[getnxt(rt)]);
    206             del(n);
    207         }
    208         //visit(rt);
    209     }
    210     return 0;
    211 }
    Hysbz3224
     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 }
    Gdufe1460
     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
    ", sum[i]);
    65         }
    66 
    67     }
    68     return 0;
    69 }
    GdufeOJ1465
  • 相关阅读:
    支付宝移动支付开发详细教程服务端采用.net mvc webapi(C#)
    微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)
    CSS border-radius 圆角
    CSS hack大全&详解(什么是CSS hack)
    一小时搞定DIV+CSS布局-固定页面开度布局
    ASP.NET MVC3开发
    .net mvc页面UI之Jquery博客日历控件
    ASP.NET MVC3开发-数据库篇之CodeFisrt开发(一)
    ASP.NET MVC页面UI之联动下拉选择控件(省、市、县联动选择)
    Jquery文本框值改变事件(支持火狐、ie)
  • 原文地址:https://www.cnblogs.com/tony-/p/8011945.html
Copyright © 2011-2022 走看看