模板大集合

【模板】KMP字符串匹配

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<string>
 6 #include<cmath>
 7 using namespace std;
 8 char a1[2000000],a2[2000000];
 9 int kmp[2000000];
10 int main()
11 {
12     scanf("%s%s",a1,a2);
13     kmp[0]=kmp[1]=0;//前一位,两位失配了,都只可能将第一位作为新的开头
14     int len1=strlen(a1),len2=strlen(a2);
15     int k;
16     k=0;
17     for(int i=1;i<len2;i++)//自己匹配自己
18     {
19         while(k&&a2[i]!=a2[k])    
20             k=kmp[k];//找到最长的前后缀重叠长度
21         kmp[i+1]=a2[i]==a2[k]?++k:0;//不相等的情况,即无前缀能与后缀重叠,直接赋值位0(注意是给下一位,因为匹配的是下一位适失配的情况)
22     }
23     k=0;
24     for(int i=0;i<len1;i++)
25     {
26         while(k&&a1[i]!=a2[k])
27             k=kmp[k];//如果不匹配,则将利用kmp数组往回跳
28         k+=a1[i]==a2[k]?1:0;//如果相等了,则匹配下一位
29         if(k==len2)
30             printf("%d
",i-len2+2);//如果已经全部匹配完毕,则输出初始位置
31     }
32     for(int i=1;i<=len2;i++)
33         printf("%d ",kmp[i]);//输出f数组
34     return 0;
35 }

【模板】ST表(线段树做的)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 struct node{
 5     int l;
 6     int r;
 7     int maxx;
 8 }t[maxn*3];
 9 int n,m,a[maxn];
10 
11 inline void read(int& x)
12 {
13    x=0;
14    register char f=getchar(),c=0;
15    while(!isdigit(f)&&f!='-')f=getchar();if(f=='-')c=1,f=getchar();
16    while(isdigit(f))x=x*10+(f^48),f=getchar();if(c)x=~x+1;
17 }
18 
19 inline void pushup(int x)
20 {
21     t[x].maxx=max(t[x<<1].maxx,t[x<<1|1].maxx);
22 }
23 
24 void bt(int x,int l,int r)
25 {
26     t[x].l=l;
27     t[x].r=r;
28     if(l==r)
29     {
30         t[x].maxx=a[l];
31         return ;
32     }
33     int mid=(l+r)>>1;
34     bt(x<<1,l,mid);
35     bt(x<<1|1,mid+1,r);
36     pushup(x);
37 }
38 
39 int query(int x,int r,int l)
40 {
41     if(t[x].l>=l&&t[x].r<=r)
42     {
43         return t[x].maxx;
44     }
45     if(t[x].l>r||t[x].r<l)
46         return 0;
47     return max(query(x<<1,r,l),query(x<<1|1,r,l));
48 }
49 
50 int main()
51 {
52     read(n);
53     read(m);
54     for(int i=1;i<=n;i++)
55         read(a[i]);
56     bt(1,1,n);
57     for(int i=1;i<=m;i++)
58     {
59         int l,r;
60         read(l);
61         read(r);
62         printf("%d
",query(1,r,l));
63     }
64     return 0;
65 }

【模板】并查集

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,z,x,y; 
 4 int father[10002];
 5 inline int find(int i)
 6 {
 7     if(i==father[i])
 8         return i;
 9     while(i!=father[i])
10         i=father[i];
11     return father[i];
12 }
13 inline void unionn(int i,int j)
14 {
15     int r1=find(i);
16     int r2=find(j);
17     if(r1==r2)
18         return ;
19     father[r2]=r1;
20     father[j]=r1;
21     return ;
22 }
23 int main()
24 {
25     cin>>n>>m;
26     for(int i=1 ; i<=n ; i++)
27     father[i]=i;
28     for(int i=1 ; i<=m ; i++)
29     {
30         cin>>z>>x>>y;
31         switch(z)
32         {
33             case 1:
34             {
35                    unionn(x,y);
36                 break;
37             }
38             case 2:
39             {
40                 if(find(x)==find(y))
41                     cout<<"Y"<<endl;
42                 else
43                     cout<<"N"<<endl;
44                 break;
45             }        
46         }    
47     }
48     return 0;
49 }

【模板】堆

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 inline void read(int& x)
 5 {
 6    x=0;
 7    register char f=getchar(),c=0;
 8    while(!isdigit(f)&&f!='-')f=getchar();if(f=='-')c=1,f=getchar();
 9    while(isdigit(f))x=x*10+(f^48),f=getchar();if(c)x=~x+1;
10 }
11 //默认排序是从大到小 
12 priority_queue<int,vector<int>,greater<int> > q;//less是从大到小,greater是从小到大。 
13 int a,b,n;
14  
15 int main()
16 {
17     read(n);
18     for(int i=1;i<=n;i++)
19     {
20         read(a);
21         if(a==1)
22         {
23             read(b);
24             q.push(b);
25         }
26         if(a==2)
27         {
28             int ans=q.top();
29             printf("%d
",ans);
30         }
31         if(a==3)
32         {
33             q.pop();
34         }
35     }
36     return 0;
37 }

【模板】负环

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=200005;
 4 
 5 inline void read(int& x)
 6 {
 7    x=0;
 8    register char f=getchar(),c=0;
 9    while(!isdigit(f)&&f!='-')f=getchar();if(f=='-')c=1,f=getchar();
10    while(isdigit(f))x=x*10+(f^48),f=getchar();if(c)x=~x+1;
11 }
12 
13 struct node{
14     int net;
15     int to;
16     int w;
17 }a[maxn*3];
18 int head[maxn];
19 int dis[maxn],n,m,cnt,T;
20 bool vis[maxn],flag;
21 
22 inline void add(int i,int j,int w)
23 {
24     a[++cnt].to=j;
25     a[cnt].net=head[i];
26     a[cnt].w=w;
27     head[i]=cnt;
28 }
29 
30 inline void spfa(int s)
31 {
32     if(flag)
33         return ;
34     vis[s]=true;
35     for(int i=head[s];i;i=a[i].net)
36     {
37         if(flag)
38             return ;
39         int v=a[i].to;
40         if(dis[v]>dis[s]+a[i].w)
41         {
42             dis[v]=dis[s]+a[i].w;
43             if(vis[v])
44             {
45                 flag=true;
46                 return ;
47             }
48             else
49             {
50                 spfa(v);
51             }
52         }
53     }
54     vis[s]=false;
55 }
56 
57 int main()
58 {
59     read(T);
60     while(T--)
61     {
62         memset(vis,false,sizeof vis);
63         memset(dis,0,sizeof(dis));
64         memset(head,0,sizeof(head));
65         flag=false;
66         cnt=0;
67         read(n);
68         read(m);
69         for(int i=1;i<=m;i++)
70         {
71             int a,b,c;
72             read(a);
73             read(b);
74             read(c);
75             add(a,b,c);
76             if(c>=0)
77             {
78                 add(b,a,c);
79             }
80         }
81         for(int i=1;i<=n;i++)
82         {
83             spfa(i);
84             if(flag)
85                 break;
86         }
87         if(flag)
88         {
89             cout<<"YE5"<<endl;
90         }
91         else
92         {
93             cout<<"N0"<<endl;
94         }
95     }
96     return 0;
97 }

【模板】可持久化线段树

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1000009; 
 4 
 5 struct node{
 6     int l;
 7     int r;
 8     int sum;
 9 }t[maxn*20];
10 int a[maxn],n,m;
11 int tot;
12 int rt[maxn];
13 
14 inline int read()
15 {
16     int x=0,f=1;
17     char ch=getchar();
18     while(ch<'0'||ch>'9')
19     {
20         if(ch=='-')f=-1;
21         ch=getchar();
22     }
23     while(ch>='0'&&ch<='9')
24     {
25         x=x*10+ch-'0';
26         ch=getchar();
27     }
28     return x*f;
29 }
30 
31 void bt(int l,int r,int &x)
32 {
33     x=++tot;
34     if(l==r)
35     {
36         t[x].sum=a[l];
37         return ;
38     }
39     int mid=(l+r)>>1;
40     bt(l,mid,t[x].l);
41     bt(mid+1,r,t[x].r);
42 }
43 
44 void update(int &x,int last,int l,int r,int pos,int sum)
45 {
46     x=++tot;
47     t[x]=t[last];
48     if(l==r)
49     {
50         t[x].sum=sum;
51         return ;
52     }
53     int mid=(l+r)>>1;
54     if(pos<=mid)
55         update(t[x].l,t[last].l,l,mid,pos,sum);
56     else
57         update(t[x].r,t[last].r,mid+1,r,pos,sum);
58 }
59 
60 inline int query(int x,int l,int r,int pos)
61 {
62     if(l==r)
63         return t[x].sum;
64     int mid=(l+r)>>1;
65     if(pos<=mid)
66         return query(t[x].l,l,mid,pos);
67     else     
68         return query(t[x].r,mid+1,r,pos);
69 }
70 
71 int main()
72 {
73     n=read();
74     m=read();
75     for(register int i=1;i<=n;i++)
76         a[i]=read();
77     bt(1,n,rt[0]);
78     for(register int i=1;i<=m;i++)
79     {
80         int v,o,p;
81         v=read();
82         o=read();
83         p=read();
84         if(o==1)
85             update(rt[i],rt[v],1,n,p,read());
86         else
87         {
88             printf("%d
",query(rt[v],1,n,p));
89             rt[i]=rt[v];
90         }
91     }
92     return 0;
93 }

【模板】线段树 1

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long  ll;
 4 inline void read(ll& x)
 5 {
 6    x=0;
 7    register char f=getchar(),c=0;
 8    while(!isdigit(f)&&f!='-')f=getchar();if(f=='-')c=1,f=getchar();
 9    while(isdigit(f))x=x*10+(f^48),f=getchar();if(c)x=~x+1;
10 }
11 struct node
12 {
13   ll l,r,sum;    
14 }t[300001];
15 ll a[100001],lazy[300001];
16 inline void bt(ll x,ll l,ll r)
17 {
18     t[x].l=l;
19     t[x].r=r;
20     if(l==r)
21     {
22         t[x].sum=a[l];
23         return;
24     }
25     bt(x*2,l,(l+r)>>1);
26     bt(x*2+1,1+((l+r)>>1),r);
27     t[x].sum=t[x*2].sum+t[x*2+1].sum;
28 }
29 inline void pushdown(ll x)
30 {
31     ll mid=(t[x].l+t[x].r)/2;
32     t[x*2].sum+=(mid-t[x].l+1)*lazy[x];
33     t[x*2+1].sum+=(t[x].r-mid)*lazy[x];
34     lazy[x*2]+=lazy[x];
35     lazy[x*2+1]+=lazy[x];
36     lazy[x]=0;
37 }
38 inline void update(ll x,ll l,ll r,ll k)
39 {
40     if(t[x].l>=l&&t[x].r<=r)
41     {
42         t[x].sum+=(t[x].r-t[x].l+1)*k;
43         lazy[x]+=k;
44         return;
45     }
46     if(t[x].r<l||t[x].l>r)
47         return ;
48     if(lazy[x])
49         pushdown(x);
50     update(x<<1,l,r,k);
51     update(x<<1|1,l,r,k);
52     t[x].sum=t[x<<1|1].sum+t[x<<1].sum;
53 }
54 inline ll query(ll x,ll l,ll r)
55 {
56     if(t[x].l>=l&&t[x].r<=r)
57     return t[x].sum;
58     if(t[x].l>r||t[x].r<l)
59     return 0;
60     if(lazy[x])
61         pushdown(x);
62     return query(x<<1,l,r)+query(x<<1|1,l,r);
63 } 
64 int main()
65 {
66     ll n,m,x,y,z,t;
67     read(n);
68     read(m);
69     for(ll i=1;i<=n;i++)
70         read(a[i]);
71     bt(1,1,n);
72     for(ll  i=1;i<=m;i++) 
73     {
74         read(t);
75         read(x);
76         read(y);
77         if(t==1)
78         {
79             read(z);
80             update(1,x,y,z);
81         }
82         else 
83             printf("%lld
",query(1,x,y));
84     }
85     return 0;
86 }

【模板】线段树 2

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn=400000+5;
  5 struct node{
  6     ll jia,ch,r,l,s;
  7 }t[maxn];
  8 ll x,y,z,a[maxn],c,n,m,p,sum,k;
  9 
 10 inline void bt(ll x,ll l,ll r)
 11 {
 12     t[x].l=l;
 13     t[x].r=r;
 14     t[x].jia=0;
 15     t[x].ch=1;
 16     if(l==r)
 17     {
 18         t[x].s=a[l];
 19         return ;
 20     }
 21     bt(x<<1,l,(r+l)>>1);
 22     bt(x<<1|1,((r+l)>>1)+1,r);
 23     t[x].s=(t[x<<1].s+t[x<<1|1].s)%p;
 24 }
 25 
 26 inline void down(ll x)
 27 {
 28     t[x*2].jia=(t[x*2].jia*t[x].ch+t[x].jia)%p;
 29     t[x*2+1].jia=(t[x*2+1].jia*t[x].ch+t[x].jia)%p;
 30     t[x*2].ch=(t[x*2].ch*t[x].ch)%p;
 31     t[x*2+1].ch=(t[x*2+1].ch*t[x].ch)%p;
 32     t[x*2].s=(t[x].jia*(t[x*2].r-t[x*2].l+1)%p+t[x*2].s*t[x].ch%p)%p;
 33     t[x*2+1].s=(t[x].jia*(t[x*2+1].r-t[x*2+1].l+1)%p+t[x*2+1].s*t[x].ch%p)%p;
 34     t[x].jia=0;
 35     t[x].ch=1;
 36 }
 37 
 38 inline void cheng(ll x,ll d,ll l,ll r)
 39 {
 40     if(t[x].l>=l&&t[x].r<=r)
 41     {
 42         t[x].s=t[x].s*d%p;
 43         t[x].jia=t[x].jia*d%p;
 44         t[x].ch=t[x].ch*d%p;
 45     }
 46     else
 47     {
 48         down(x);
 49         ll mid=(t[x].r+t[x].l)>>1;
 50         if(mid>=l)
 51             cheng(x<<1,d,l,r);
 52         if(mid<r)
 53             cheng(x<<1|1,d,l,r);
 54         t[x].s=(t[x<<1].s+t[x<<1|1].s)%p;    
 55     }
 56     return ;
 57 }
 58 
 59 inline void jf(ll x,ll d,ll l,ll r)
 60 {
 61     if(t[x].l>=l&&t[x].r<=r)
 62     {
 63         t[x].jia=(t[x].jia+d)%p;
 64         t[x].s=((t[x].r-t[x].l+1)*d+t[x].s)%p;
 65     }
 66     else
 67     {
 68         down(x);
 69         ll mid=(t[x].r+t[x].l)>>1;
 70         if(mid>=l)
 71             jf(x<<1,d,l,r);
 72         if(mid<r)
 73             jf(x<<1|1,d,l,r);
 74         t[x].s=(t[x<<1].s+t[x<<1|1].s)%p;
 75     }
 76     return ;
 77 }
 78 
 79 long long qh(long long l,long long r,long long x)
 80 {
 81     if(t[x].r<=r&&t[x].l>=l)
 82         return t[x].s%p;
 83     else 
 84     {
 85         down(x);
 86         long long ans=0;
 87         long long mid=(t[x].l+t[x].r)>>1;
 88         if(mid>=l)ans=qh(l,r,x<<1)%p;
 89         if(mid<r)ans=ans+qh(l,r,x<<1|1);
 90         return ans%p;
 91     }
 92 }
 93 
 94 int main()
 95 {
 96     scanf("%lld%lld%lld",&n,&m,&p);
 97     for(int i=1;i<=n;i++)
 98     {
 99         scanf("%lld",&a[i]);
100     }
101     bt(1,1,n);
102     for(int i=1;i<=m;i++)
103     {
104         scanf("%lld",&c);
105         if(c==1)
106         {
107             scanf("%lld%lld%lld",&x,&y,&k);
108             cheng(1,k,x,y);
109         }
110         if(c==2)
111         {
112             scanf("%lld%lld%lld",&x,&y,&k);
113             jf(1,k,x,y);
114         }
115         if(c==3)
116         {
117             scanf("%lld%lld",&x,&y);
118             printf("%lld
",qh(x,y,1));
119         }
120     }
121     return 0;
122 }

【模板】最近公共祖先(LCA)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 inline void read(int& x) 
 5 {
 6    x=0;
 7    register char f=getchar(),c=0;
 8    while(!isdigit(f)&&f!='-') f=getchar();
 9    if(f=='-') c=1,f=getchar();
10    while(isdigit(f)) x=x*10+(f^48),f=getchar();
11    if(c) x=~x+1;
12 }
13 
14 const int maxn=500000+5;
15 struct node{
16     int net;
17     int to;
18 }a[maxn*2];
19 int n,m,s;
20 int k=0;
21 int head[maxn],d[maxn],p[maxn][21];
22 int cnt;
23 
24 inline void add(int i,int j)
25 {
26     a[++cnt].to=j;
27     a[cnt].net=head[i];
28     head[i]=cnt;
29 }
30 
31 inline void dfs(int u,int fa)
32 {
33     d[u]=d[fa]+1;
34     p[u][0]=fa;
35     for(register int i=1;(1<<i)<=d[u];i++)
36         p[u][i]=p[p[u][i-1]][i-1];
37     for(register int i=head[u];i;i=a[i].net)
38     {
39         int v=a[i].to;
40         if(v!=fa)
41         {
42             dfs(v,u);
43         }
44     }
45 }
46 
47 inline int LCA(int a,int b)
48 {
49     if(d[a]>d[b])
50         swap(a,b);
51     for(register int i=20;i>=0;i--)
52         if(d[a]<=d[b]-(1<<i))
53             b=p[b][i];
54     if(a==b)
55         return a;
56     for(register int i=20;i>=0;i--)
57     {
58         if(p[a][i]==p[b][i])
59             continue;
60         else
61         {
62             a=p[a][i];
63             b=p[b][i];
64         }    
65     }
66     return p[a][0];
67 }
68 
69 int main()
70 {
71     read(n);
72     read(m);
73     read(s);
74     for(register int i=1;i<n;i++)
75     {
76         int a,b;
77         read(a);
78         read(b);
79         add(a,b);
80         add(b,a);
81     }
82     dfs(s,0);
83     for(register int i=1;i<=m;i++)
84     {
85         int a,b;
86         read(a);
87         read(b);
88         printf("%d
",LCA(a,b));
89     }
90     return 0;
91 } 

【模板】最小生成树(kruskal)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=200000;
 5 struct node{
 6     ll u;
 7     ll v;
 8     ll w;
 9 }a[maxn+5];
10 ll fa[maxn+5];
11 int n,m;
12 ll ans,cnt;
13 
14 inline bool cmp(node a,node b)
15 {
16     return a.w<b.w;
17 }
18 
19 inline ll find(ll x)
20 {
21     if(fa[x]!=x)
22         fa[x]=find(fa[x]);
23     return fa[x];
24 }
25 
26 inline void kruskal()
27 {
28     sort(a,a+m,cmp);
29     for(int i=0;i<m;i++)
30     {
31         ll u=a[i].u;
32         ll v=a[i].v;
33         ll w=a[i].w;
34         ll f=find(u);
35         ll ff=find(v);
36         if(f==ff)
37             continue;
38         ans+=w;
39         fa[ff]=f;
40         cnt++;
41         if(cnt==n-1)
42             break;
43     }
44 }
45 
46 int main()
47 {
48     scanf("%d%d",&n,&m);
49     for(int i=1;i<=n;i++)
50         fa[i]=i;
51     for(int i=0;i<m;i++)
52     {
53         scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].w);
54     }
55     kruskal();
56     if(cnt!=n-1)
57         printf("orz");
58     printf("%lld
",ans);
59     return 0;
60 }

【模板】最小生成树(prim)邻接表

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #define INF 0x7fffffff
 5 const int maxn=500000+5;
 6 
 7 using namespace std;
 8 
 9 struct node{
10     int to,nxt,w;
11 }a[maxn];
12 
13 struct heapnode{
14     int point,dist;
15     bool operator > (const heapnode &o) const{
16         return dist>o.dist;
17     }
18 };
19 
20 priority_queue<heapnode,vector<heapnode>,greater<heapnode> >q;
21 
22 bool vis[maxn];
23 int n,m,s,head[maxn],dis[maxn],tot,ans,cnt;
24 
25 void add(int u,int v,int w)
26 {
27     a[++tot].to=v;
28     a[tot].w=w;
29     a[tot].nxt=head[u];
30     head[u]=tot;
31 }
32 
33 int main()
34 {
35     memset(head,-1,sizeof(head));
36     scanf("%d%d",&n,&m);
37     s=1;
38     for(int i=1;i<=m;++i)
39     {
40         int f,g,w;
41         scanf("%d%d%d",&f,&g,&w);
42         add(f,g,w);
43         add(g,f,w);
44     }
45     fill(dis+1,dis+n+1,INF);
46     dis[s]=0;
47     vis[s]=true;
48     for(int i=head[s];i!=-1;i=a[i].nxt)
49     {
50         q.push((heapnode){a[i].to,a[i].w});
51         dis[a[i].to]=a[i].w;
52     }
53     while(!q.empty()&&cnt<n)
54     {
55         heapnode now=q.top();
56         q.pop();
57         if(vis[now.point])  
58             continue;
59         ++cnt;
60         ans+=now.dist;
61         vis[now.point]=true;
62         for(int i=head[now.point];i;i=a[i].nxt)
63         {
64             if(dis[a[i].to]>a[i].w)
65             {
66                 dis[a[i].to]=a[i].w;
67                 q.push((heapnode){a[i].to,a[i].w});
68             }
69         }
70     }
71     if(n) 
72         printf("%d
",ans);
73     else 
74         printf("orz");
75     return 0;
76 }

【模板】最小生成树(prim)邻接矩阵

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <queue>//同上 
 8 using namespace std;
 9 struct number{
10     int x,i;
11     bool operator < (const number &a) const {
12         return x>a.x;//最小值优先,因为默认是大根堆的说。。。 
13     }
14 }A,B;//中转站而已 
15 priority_queue <number> q;//
16 int map[5005][5005],n,m,a,b,c,ans;
17 bool v[5005];
18 int main()
19 {
20     memset(v,false,sizeof(v));
21     memset(map,-1,sizeof(map));
22     scanf("%d%d",&n,&m);
23     for (int i=0;i<m;i++)
24     {
25         scanf("%d%d%d",&a,&b,&c);
26         if (map[a][b]==-1||c<map[a][b]) 
27             map[a][b]=c;
28         if (map[b][a]==-1||c<map[b][a]) 
29             map[b][a]=c;
30     }
31     v[1]=true;
32     for (int i=1;i<=n;i++)
33         if (map[1][i]!=-1)
34         {
35             A.x=map[1][i];
36             A.i=i;
37             q.push(A);
38         }
39     for (int i=1;i<n;i++)
40     {
41         if (q.empty())
42         {
43             printf("orz");
44             return 0;
45         }
46         B=q.top();
47         q.pop();
48         while (v[B.i])
49         {
50             B=q.top();
51             q.pop();
52             if (q.empty())
53             {
54                 printf("orz");
55                 return 0;
56             }
57         }
58         ans+=B.x;
59         v[B.i]=true;
60         for (int j=1;j<=n;j++)
61         if (map[B.i][j]!=-1&&!v[j])
62         {
63             A.x=map[B.i][j];
64             A.i=j;
65             q.push(A);
66         }
67     }
68     printf("%d
",ans);
69     return 0;
70 }

LCA【tarjan】

 1 //LCA tarjan
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 const int maxn = 1000;
 5 int ask[maxn][maxn];//保存询问 
 6 int ans[maxn];//保存祖先i出现过的次数 
 7 int n,m;
 8 vector<int> g[maxn];//保存儿子 
 9 int root;//树的根 
10 bool visit[maxn];
11 bool isroot[maxn];
12 int father[maxn];
13 int Find(int x)
14 {
15     if(father[x] == x) 
16         return x;
17     else 
18         return father[x] = Find(father[x]);
19 }
20 void init()
21 {
22     memset(ans,0,sizeof(ans));
23     memset(visit,false,sizeof(visit));
24     memset(isroot,true,sizeof(isroot));
25     memset(ask,0,sizeof(ask));
26     for(int i = 1; i <= n; i++)
27     {
28         g[i].clear();
29         father[i] = i;
30     }
31 
32 }
33 void LCA(int root)
34 {
35     for(int i = 1; i <= n; i++)
36     {
37         if(visit[i]&&ask[root][i])
38         {
39             ans[Find(i)] += ask[root][i];
40         }
41     }
42     visit[root] = true;
43     for(int i = 0; i < g[root].size(); i++)
44     {
45         int term = g[root][i];
46         LCA(term);
47         father[term] = root;
48     }
49 }
50 int main()
51 {
52     while(~scanf("%d",&n))
53     {
54         init();
55         int f,s,num;
56         for(int i = 1; i <= n; i++)
57         {
58             scanf("%d:(%d)",&f,&num);
59             for(int j = 1; j <= num; j++)
60             {
61                 scanf(" %d",&s);
62                 isroot[s] = false;
63                 g[f].push_back(s);
64             }
65         }
66         for(int i = 1; i <= n; i++)
67         {
68             if(isroot[i])
69             {
70                 root = i;
71                 break;
72             }
73         }
74         scanf("%d",&m);
75         int u,v;
76         for(int i = 1; i <= m; i++)
77         {
78             scanf(" (%d %d)",&u,&v);
79             ask[u][v]++;
80             ask[v][u]++;
81         }
82         LCA(root);
83         for(int i = 1; i <= n; i++)
84         {
85             if(ans[i])
86             {
87                 printf("%d:%d
",i,ans[i]);
88             }
89         }
90     }
91     return 0;
92 }

LCA【倍增法】

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 inline void read(int& x)
 5 {
 6    x=0;
 7    register char f=getchar(),c=0;
 8    while(!isdigit(f)&&f!='-')
 9    f=getchar();
10    if(f=='-')
11    c=1,f=getchar();
12    while(isdigit(f))
13    x=x*10+(f^48),f=getchar();
14    if(c)
15    x=~x+1;
16 }
17 
18 const int maxn=500000+5;
19 struct node{
20     int net;
21     int to;
22 }a[maxn*2];
23 int n,m,s,cnt;
24 int head[maxn*2],dep[maxn*2],bz[maxn][22];
25 
26 inline void add(int i,int j)
27 {
28     a[++cnt].to=j;
29     a[cnt].net=head[i];
30     head[i]=cnt;
31 }
32 
33 inline void dfs(int u,int fa)
34 {
35     dep[u]=dep[fa]+1;
36     bz[u][0]=fa;
37     for(register int i=1;(1<<i)<=dep[u];i++)
38         bz[u][i]=bz[bz[u][i-1]][i-1];
39     for(register int i=head[u];i;i=a[i].net)
40     {
41         int v=a[i].to;
42         if(v!=fa)
43         {
44             dfs(v,u);
45         }
46     }
47 }
48 
49 inline int lca(int a,int b)
50 {
51     if(dep[a]>dep[b])
52         swap(a,b);
53     for(register int i=20;i>=0;i=~(-i))
54         if(dep[a]<=dep[b]-(1<<i))
55         {
56             b=bz[b][i];
57         }
58     if(a==b)
59         return a;
60     for(register int i=20;i>=0;i=~(-i))
61     {
62         if(bz[a][i]==bz[b][i])
63             continue;
64         else
65         {
66             a=bz[a][i];
67             b=bz[b][i];
68         }
69     }
70     return bz[a][0];
71 }
72 
73 int main()
74 {
75     read(n);
76     read(m);
77     read(s);
78     for(register int i=1;i<n;i=-(~i))
79     {
80         int a,b;
81         read(a);
82         read(b);
83         add(a,b);
84         add(b,a);
85     }
86     dfs(s,0);
87     for(register int i=1;i<=m;i=-(~i))
88     {
89         int a,b;
90         read(a);
91         read(b);
92         printf("%d
",lca(a,b));
93     }
94     return 0;
95 }

LCA【树剖法】

 1 //LCA树剖法
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 struct node
 5 {
 6     int y,next;
 7 }e[201000];
 8 int n,m,len,z,head[201000];
 9 int dep[201000];//用来保存当前节点的深度 
10 int f[201000];//保存当前节点的父亲 
11 int top[201000];//保存当前节点的所在链的顶端节点 
12 int son[201000];//保存重儿子 
13 int size[201000];//用来保存以x为根的子树节点个数 
14 
15 inline int read()
16 {
17     int x=0,f=1;  char ch=getchar();
18     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
19     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
20     return x*f;
21 }
22 
23 void insert(int xx,int yy)
24 {
25     e[++len].next=head[xx];
26     head[xx]=len;
27     e[len].y=yy;
28 }
29 
30 void dfs1(int x)
31 {
32     dep[x]=dep[f[x]]+1;
33     size[x]=1;
34     for(int i=head[x];i;i=e[i].next)
35     {
36         if(e[i].y!=f[x]&&!f[e[i].y])
37         {
38             f[e[i].y]=x;
39             dfs1(e[i].y);
40             size[x]+=size[e[i].y];
41             if(size[son[x]]<size[e[i].y])
42                 son[x]=e[i].y;
43         }
44     }
45 }
46 
47 void dfs2(int x)
48 {
49     if(x==son[f[x]])
50         top[x]=top[f[x]];
51     else
52         top[x]=x;
53     for(int i=head[x];i;i=e[i].next)
54         if(f[e[i].y]==x)
55             dfs2(e[i].y);
56 }
57 
58 int LCA(int xx,int yy)
59 {
60     while(top[xx]!=top[yy])
61     {
62         if(dep[top[xx]]>dep[top[yy]])
63             xx=f[top[xx]];
64         else
65             yy=f[top[yy]];
66     }
67     if(dep[xx]<dep[yy])
68         return xx;
69     else 
70         return yy;
71 }
72 
73 int main()
74 {
75     n=read();
76     m=read();
77     for(int i=1;i<n;i++)
78     {
79         int xx=read();
80         int yy=read();
81         insert(xx,yy);
82         insert(yy,xx);
83     }
84     dfs1(1);
85     dfs2(1);
86     for(int i=1;i<=m;i++)
87     {
88         int xx=read(),yy=read();
89         printf("%d
",LCA(xx,yy));
90     }
91     return 0;
92 }

快速幂

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll b,p,k;
 5 inline ll qpow(ll a,ll b)
 6 {
 7     ll ans=1;
 8     while(b)
 9     {
10         if(b&1)
11             ans=(ans*a)%k;
12         b=b>>1;
13         a=(a*a)%k;
14     }
15     return ans;
16 }
17 int main()
18 {
19     cin>>b>>p>>k;
20     cout<<b<<"^"<<p<<" "<<"mod "<<k<<"="<<qpow(b,p);
21     return 0;
22 }

求树上两点距离(边权为1时)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int deep[100005];
 5 int ru[100005];
 6 int fa[100005];
 7 int head[100005],cnt;
 8 struct node {
 9     int v,next;
10 } e[200005];
11 inline void add(int u,int v) {
12     e[++cnt].next=head[u];
13     e[cnt].v=v;
14     head[u]=cnt;
15 }
16 inline void Deep_pre(int x,int dep) {
17     deep[x]=dep;
18     for(register int i=head[x]; i; i=e[i].next) {
19         if(e[i].v==fa[x]) continue;
20         fa[e[i].v]=x;
21         Deep_pre(e[i].v,dep+1);
22     }
23 }
24 inline int lca(int x,int y) {
25     if(deep[x]>deep[y])swap(x,y);
26     while(deep[x]!=deep[y]) {
27         y=fa[y];
28     }
29     while(x!=y) {
30         x=fa[x];
31         y=fa[y];
32     }
33     return x;
34 }
35 int main() {
36     scanf("%d",&n);
37     for(register int i=1,u,v; i<n; ++i) {
38         scanf("%d%d",&u,&v);
39         add(u,v);
40         add(v,u);
41     }
42     int root=1;
43     fa[root]=0;
44     Deep_pre(root,1);
45     int m,ui,vi;
46     scanf("%d",&m);
47     for(register int i=1; i<=m; ++i) {
48         scanf("%d%d",&ui,&vi);
49         int LCA=lca(ui,vi);
50         printf("%d
",deep[ui]+deep[vi]-2*deep[LCA]);
51     }
52     return 0;
53 }
54 /*
55 5
56 1 3
57 2 4
58 3 5
59 2 3
60 10
61 1 3
62 2 4
63 5 3
64 5 1
65 4 2
66 1 5
67 1 4
68 1 3
69 2 4
70 2 1
71 */

 平衡树-splay

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn=110000;
  5 
  6 struct node{
  7     int d,n,c,f,son[2];//d为值,f为父亲的编号,c为控制的节点数,n为同值的节点个数 
  8 }t[maxn*5];
  9 int len,root;
 10 
 11 inline void update(int x)//更新x所控制的节点数 
 12 {
 13     int lc=t[x].son[0],rc=t[x].son[1];
 14     t[x].c=t[lc].c+t[rc].c+t[x].n;
 15 }
 16 
 17 inline void add(int d,int f)//添加值为d的点,认f为父亲,同时,f也认它为孩子 
 18 {
 19     len++;
 20     t[len].d=d;
 21     t[len].n=1;
 22     t[len].c=1;
 23     t[len].f=f;
 24     if(d<t[f].d)
 25         t[f].son[0]=len;
 26     else
 27         t[f].son[1]=len;
 28     t[len].son[0]=t[len].son[1]=0;
 29 }
 30 
 31 inline void rotate(int x,int w)//左旋(x,0)或者右旋(x,1) 
 32 {
 33     int f=t[x].f,ff=t[f].f;//x在旋转之前,要确定x的父亲f和爷爷ff
 34     //下来建立关系 
 35     int r,R;//r代表儿辈,R表示父辈 
 36     //有4个角色:我x,我的儿子,我的父亲,我的爷爷 
 37     r=t[x].son[w];R=f;//x的儿子->准备当新儿子 
 38     t[R].son[1-w]=r;
 39     if(r!=0)
 40         t[r].f=R;
 41     
 42     r=x;R=ff;//x->准备当新儿子 
 43     if(t[R].son[0]==f)
 44         t[R].son[0]=r;
 45     else     
 46         t[R].son[1]=r;
 47     t[r].f=R;
 48     
 49     r=f;R=x;//x的父亲->准备当新儿子 
 50     t[R].son[w]=r;
 51     t[r].f=R;
 52     
 53     update(f);//先更新处于下层的点f 
 54     update(x);//再更新上层的x 
 55 }
 56 
 57 inline void splay(int x,int rt)//该函数功能是为了让x变成rt的孩子(左右都可以) 
 58 {
 59     while(t[x].f!=rt)//如果x的爷爷是rt,那么x只需要旋转一次(相当于跳一层) 
 60     {
 61         int f=t[x].f,ff=t[f].f;
 62         if(ff==rt)
 63         {
 64             if(t[f].son[0]==x)
 65                 rotate(x,1);
 66             else
 67                 rotate(x,0);
 68         }
 69         else
 70         {
 71             if(t[ff].son[0]==f&&t[f].son[0]==x)
 72             {
 73                 rotate(f,1);rotate(x,1);
 74             }
 75             else if(t[ff].son[1]==f&&t[f].son[1]==x)
 76             {
 77                 rotate(f,0);rotate(x,0);
 78             }
 79             else if(t[ff].son[0]==f&&t[f].son[1]==x)
 80             {
 81                 rotate(x,0);rotate(x,1);
 82             }
 83             else if(t[ff].son[1]==f&&t[f].son[0]==x)
 84             {
 85                 rotate(x,1);rotate(x,0);
 86             }
 87         }
 88     }
 89     if(rt==0)
 90         root=x;
 91 }
 92 
 93 inline int findip(int d)//找值为d的节点地址,补充:如果不存在d,有可能是接近d的(或大或小)
 94 {
 95     int x=root;
 96     while(t[x].d!=d)
 97     {
 98         if(d<t[x].d)
 99         {
100             if(t[x].son[0]==0)
101                 break;
102             else
103                 x=t[x].son[0];
104         }
105         else
106         {
107             if(t[x].son[1]==0)
108                 break;
109             else
110                 x=t[x].son[1];
111         }
112     }
113     return x;
114 }
115 
116 inline void insert(int d)//插入数值为d的一个节点 
117 {
118     if(root==0)
119     {
120         add(d,0);
121         root=len;
122         return ;
123     }
124     int x=findip(d);
125     if(t[x].d==d)
126     {
127         t[x].n++;
128         update(x);
129         splay(x,0);
130     }
131     else
132     {
133         add(d,x);
134         update(x);
135         splay(len,0);
136     }
137 }
138 
139 inline void del(int d)//删除数值为d的一个节点 
140 {
141     int x=findip(d);
142     splay(x,0);//找人,并且让y当树根 
143     if(t[x].n>1)//多重身份,就不用删点 
144     {
145         t[x].n--;
146         update(x);
147         return ;
148     }
149     if(t[x].son[0]==0&&t[x].son[1]==0)
150     {
151         root=0;
152         len=0;
153     }
154     else if(t[x].son[0]==0&&t[x].son[1]!=0)
155     {
156         root=t[x].son[1];
157         t[root].f=0;
158     }
159     else if(t[x].son[0]!=0&&t[x].son[1]==0)
160     {
161         root=t[x].son[0];
162         t[root].f=0;
163     }
164     else
165     {
166         int p=t[x].son[0];
167         while(t[p].son[1]!=0)
168             p=t[p].son[1];
169         splay(p,x);
170         
171         int r=t[x].son[1],R=p;
172         
173         t[R].son[1]=r;
174         t[r].f=R;
175         
176         root=R;
177         t[root].f=0;
178         update(R);
179     }
180 }
181 
182 inline int findrank(int d)//找排名 
183 {
184     int x=findip(d);
185     splay(x,0);
186     return t[t[x].son[0]].c+1;
187 }
188 
189 inline int findshuzhi(int k)//找排名为k的值 
190 {
191     int x=root;
192     while(true)
193     {
194         int lc=t[x].son[0],rc=t[x].son[1];
195         if(k<=t[lc].c) 
196             x=lc;//去左孩子查找 
197         else if(k>t[lc].c+t[x].n)
198         {
199             k-=t[lc].c+t[x].n;
200             x=rc;
201         }//去右孩子查找 
202         else 
203             break;//就是你 
204     }
205     splay(x,0);
206     return t[x].d;
207 }
208 
209 inline int findqianqu(int d)//找前驱 
210 {
211     int x=findip(d);
212     splay(x,0);
213     if(d<=t[x].d&&t[x].son[0]!=0) 
214     {
215         x=t[x].son[0];
216         while(t[x].son[1]!=0)
217             x=t[x].son[1];
218     }
219     if(t[x].d>=d)//如果是if(t[x].d>d)则找到的是:小于等于d的前驱 
220         x=0;
221         return t[x].d;
222 }
223 
224 inline int findhouji(int d)//找后继 
225 {
226     int x=findip(d);
227     splay(x,0);
228     if(t[x].d<=d&&t[x].son[1]!=0)
229     {
230         x=t[x].son[1];
231         while(t[x].son[0]!=0)
232             x=t[x].son[0];
233     }
234     if(t[x].d<=d)
235         x=0;
236     return t[x].d;
237 }
238 
239 int main()
240 {
241     int n,opt,x;
242     scanf("%d",&n);
243     for(int i=1;i<=n;i++)
244     {
245         scanf("%d%d",&opt,&x);
246         if(opt==1)
247         {
248             insert(x);
249         }
250         if(opt==2)
251         {
252             del(x);
253         }
254         if(opt==3)
255         {
256             printf("%d
",findrank(x));
257         }
258         if(opt==4)
259         {
260             printf("%d
",findshuzhi(x));
261         }
262         if(opt==5)
263         {
264             printf("%d
",findqianqu(x));
265         }
266         if(opt==6)
267         {
268             printf("%d
",findhouji(x));
269         }
270     }
271     return 0;
272 }

 分块

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+7;
 5 
 6 int block,belong[maxn],num,l[maxn],r[maxn],n,q;
 7 ll a[maxn],Max[maxn];
 8 
 9 inline void bt()
10 {
11     block=sqrt(n);
12     num=n/block;
13     if(n%block)
14         num++;
15     for(int i=1;i<=num;i++)
16         l[i]=(i-1)*block+1,r[i]=i*block;
17     r[num]=n;
18     for(int i=1;i<=n;i++)
19         belong[i]=(i-1)/block+1;
20     for(int i=1;i<=num;i++)
21     {
22         for(int j=l[i];j<=r[i];j++)
23             Max[i]=max(Max[i],a[j]);
24     }
25 }
26 
27 inline void update(int x,int y)
28 {
29     a[x]+=y;
30     Max[belong[x]]=max(Max[belong[x]],a[x]);
31 }
32 
33 inline ll ask(int x,int y)
34 {
35     ll ans=0;
36     if(belong[x]==belong[y])
37     {
38         for(int i=x;i<=y;i++)
39             ans=max(a[i],ans);
40         return ans;
41     }
42     for(int i=x;i<=r[belong[x]];i++)
43     {
44         ans=max(ans,a[i]);
45     }
46     for(int i=belong[x]+1;i<belong[y];i++)
47     {
48         ans=max(ans,Max[i]);
49     }
50     for(int i=belong[y];i<=y;i++)
51     {
52         ans=max(ans,a[i]);
53     }
54     return ans;
55 }
56 
57 int main()
58 {
59     scanf("%d%d",&n,&q);
60     bt();
61     for(int i=1;i<=q;i++)
62     {
63         int op,l,r;
64         scanf("%d%d%d",&op,&l,&r);
65         if(op==1)
66             update(l,r);
67         else 
68             printf("%lld
",ask(l,r));
69     }
70     return 0;
71 }

文艺平衡树(翻转区间)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn=110000;
  5 
  6 struct node{
  7     int d,c,n,f,son[2];
  8     bool fz;
  9     node(){fz=false;}
 10 }t[maxn];
 11 int len,root;
 12 void add(int d,int f)
 13 {
 14     len++;
 15     t[len].d=d;t[len].f=f;
 16     t[len].n=t[len].c=1;
 17     t[len].son[0]=t[len].son[1]=0;
 18     if(d<t[f].d)
 19         t[f].son[0]=len;
 20     else
 21         t[f].son[1]=len;
 22 }
 23 
 24 inline void update(int x)
 25 {
 26     int lc=t[x].son[0],rc=t[x].son[1];
 27     t[x].c=t[lc].c+t[rc].c+t[x].n;
 28 }
 29 
 30 inline void whfz(int x)
 31 {
 32     t[x].fz=false;
 33     int lc=t[x].son[0],rc=t[x].son[1];
 34     swap(t[x].son[0],t[x].son[1]);
 35     t[lc].fz=1-t[lc].fz;
 36     t[rc].fz=1-t[rc].fz;
 37 }
 38 
 39 inline int findip(int d)
 40 {
 41     int x=root;
 42     while(t[x].d!=d)
 43     {
 44         if(d<t[x].d)    
 45         {
 46             if(t[x].son[0]==0)
 47                 break;
 48             x=t[x].son[0];
 49         }
 50         else
 51         {
 52             if(t[x].son[1]==0)
 53                 break;
 54             x=t[x].son[1];
 55         }
 56     }
 57     return x;
 58 }
 59 
 60 inline void rotate(int x,int w)
 61 {
 62     int f=t[x].f,ff=t[f].f;
 63     int r,R;
 64     
 65     r=t[x].son[w],R=f;
 66     t[R].son[1-w]=r;
 67     if(r!=0)
 68         t[r].f=R;
 69         
 70     r=x,R=ff;
 71     if(t[R].son[0]==f)
 72         t[R].son[0]=r;
 73     else
 74         t[R].son[1]=r;
 75     t[r].f=ff;
 76     
 77     r=f,R=x;
 78     t[R].son[w]=r;
 79     t[r].f=R;
 80     
 81     update(f);
 82     update(x);
 83 }
 84 
 85 inline void splay(int x,int rt)
 86 {
 87     while(t[x].f!=rt)
 88     {
 89         int f=t[x].f,ff=t[f].f;
 90         if(ff==rt)
 91         {
 92             if(t[x].fz==true)
 93                 whfz(f);
 94             if(t[f].son[0]==x)
 95                 rotate(x,1);
 96             else
 97                 rotate(x,0);
 98         }
 99         else
100         {
101             if(t[x].fz==true)
102                 whfz(x);
103             if(t[f].fz==true)
104             {
105                 t[f].fz=false;
106                 t[x].fz=true;
107             }
108             if(t[f].son[0]==x&&t[ff].son[0]==f)
109             {
110                 rotate(f,1);rotate(x,1);
111             }
112             else if(t[f].son[1]==x&&t[ff].son[1]==f)
113             {
114                 rotate(f,0);rotate(x,0);
115             }
116             else if(t[f].son[0]==x&&t[ff].son[1]==f)
117             {
118                 rotate(x,1);rotate(x,0);
119             }
120             else if(t[f].son[1]==x&&t[ff].son[0]==f)
121             {
122                 rotate(x,0);rotate(x,1);
123             }
124         }
125     }
126     if(rt==0)
127         root=x;
128 }
129 
130 inline void insert(int d)
131 {
132     if(root==0)
133     {
134         add(d,0);
135         root=len;
136         return ;
137     }
138     int x=findip(d);
139     if(t[x].d==d)
140     {
141         t[x].n++;
142         update(d);
143         splay(x,0);
144     }
145     else
146     {
147         add(d,x);
148         update(x);
149         splay(len,0);
150     }
151 }
152 
153 inline int findrank(int k)
154 {
155     int x=root;
156     while(true)
157     {
158         if(t[x].fz==true)
159             whfz(x);
160         int lc=t[x].son[0],rc=t[x].son[1];
161         if(k<=t[lc].c)
162             x=lc;
163         else if(k>t[lc].c+t[x].n)
164         {
165             k-=t[lc].c+t[x].n;
166             x=rc;
167         }
168         else
169             break;
170     }
171     splay(x,0);
172     return x;
173 }
174 
175 inline void fz(int x,int y)
176 {
177     int lc=findrank(x-1),rc=findrank(y+1);
178     splay(lc,0);
179     splay(rc,lc);
180     int p=t[rc].son[0];
181     t[p].fz=1-t[p].fz;
182     splay(p,0);
183 }
184 
185 int n,m;
186 int a[maxn],llen;
187 
188 void dfs(int x)
189 {
190     if(t[x].fz==true)    
191         whfz(x);
192     int lc=t[x].son[0],rc=t[x].son[1];
193     if(lc==0&&rc==0)
194     {
195         a[++llen]=t[x].d;
196         return ;
197     }
198     if(lc!=0)
199         dfs(lc);
200     a[++llen]=t[x].d;
201     if(rc!=0)
202         dfs(rc);
203 }
204 
205 int main()
206 {
207     scanf("%d%d",&n,&m);
208     len=0,root=0;
209     for(int i=1;i<=n;i++)
210         insert(i);
211     insert(n+1);insert(n+2);
212     for(int i=1;i<=m;i++)
213     {
214         int x,y;
215         scanf("%d%d",&x,&y);
216         x++;
217         y++;
218         fz(x,y);
219     }
220     llen=0;
221     dfs(root);
222     for(int i=2;i<llen-1;i++)
223         printf("%d ",a[i]-1);
224     printf("%d
",a[llen-1]-1);
225     return 0;
226 }

 主席树(求静态区间第K小)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=210000;
 4 int n,m,cnt;
 5 struct node
 6 {
 7     int l;
 8     int r;
 9     int sum;
10 } t[maxn*60];
11 int rk[maxn],rt[maxn];
12 struct p
13 {
14     int x;
15     int pp;
16     bool operator < (const p &_) const
17     {
18         return x<_.x;
19     }
20 } a[maxn];
21 
22 inline void bt(int &num,int &x,int l,int r)
23 {
24     t[cnt++]=t[x];
25     x=cnt-1;
26     ++t[x].sum;
27     if(l==r)
28         return ;
29     int mid=(l+r)>>1;
30     if(num<=mid)
31         bt(num,t[x].l,l,mid);
32     else
33         bt(num,t[x].r,mid+1,r);
34 
35 }
36 
37 inline int query(int i,int j,int k,int l,int r)
38 {
39     if(l==r)
40         return l;
41     int tt=t[t[j].l].sum-t[t[i].l].sum;
42     int mid=(l+r)>>1;
43     if(k<=tt)
44         return query(t[i].l,t[j].l,k,l,mid);
45     else
46         return query(t[i].r,t[j].r,k-tt,mid+1,r);
47 }
48 
49 int main()
50 {
51     t[0].l=t[0].r=t[0].sum;
52     rt[0]=0;
53     scanf("%d%d",&n,&m);
54     for(int i=1; i<=n; i++)
55     {
56         scanf("%d",&a[i].x);
57         a[i].pp=i;
58     }
59     sort(a+1,a+1+n);
60     for(int i=1; i<=n; i++)
61         rk[a[i].pp]=i;
62     cnt=1;
63     for(int i=1; i<=n; i++)
64     {
65         rt[i]=rt[i-1];
66         bt(rk[i],rt[i],1,n);
67     }
68     while(m--)
69     {
70         int i,j,k;
71         scanf("%d%d%d",&i,&j,&k);
72         printf("%d
",a[query(rt[i-1],rt[j],k,1,n)].x);
73     }
74     return 0;
75 }
原文地址:https://www.cnblogs.com/Hammer-cwz-77/p/8545694.html