codeforces #548 div2

Posted uuzlove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces #548 div2相关的知识,希望对你有一定的参考价值。

A.

题解:考虑最后一位的奇偶性就行

技术图片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pii pair<int,int>
 4 #define mp(a,b) make_pair(a,b)
 5 using namespace std;
 6 #define maxn 100005
 7 ll ans=0; 
 8 int n;
 9 char s[maxn];
10 int main()
11 {
12     scanf("%d",&n);
13     scanf("%s",s+1);
14     for(int i=1;i<=n;++i)
15     {
16         if(!((s[i]-0)&1))ans+=1ll*i;
17     }
18     printf("%I64d
",ans);
19     return 0;
20 }
View Code

 

B.

题解:答案一定是从最后往前的连续一段,扫一下统计一下,每次-1和a[i]取个min

技术图片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pii pair<int,int>
 4 #define maxn 200005
 5 #define mp(a,b) make_pair(a,b)
 6 using namespace std;
 7 int n;
 8 ll a[maxn];
 9 int main()
10 {
11     scanf("%d",&n);
12     for(int i=1;i<=n;++i)scanf("%I64d",&a[i]);
13     ll ans=0;
14     ll x=a[n]+1;
15     for(int i=n;i;--i)
16     {
17         x=min(x,a[i]);
18         ans=ans+x;
19         x--;
20         if(!x)break;
21     }
22     printf("%I64d
",ans);
23     return 0;
24 }
View Code

 

C.

题解:考虑容斥,算出总方案数-全是红边的方案数

总方案数就是n^k,全是红边的方案数就是把黑边去掉的连通块中,设连通块大小为s,就是s^k

并查集维护

技术图片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pii pair<int,int>
 4 #define mp(a,b) make_pair(a,b)
 5 using namespace std;
 6 const ll mod = 1000000007;
 7 #define maxn 100005
 8 int n,k;
 9 int fa[maxn];
10 ll sz[maxn];
11 int find(int x)
12 {
13     if(fa[x]==x)return x;
14     else return fa[x]=find(fa[x]);
15 }
16 ll fastpow(ll a,ll p)
17 {
18     ll ans=1;
19     while(p)
20     {
21         if(p&1)ans=ans*a%mod;
22         a=a*a%mod;p>>=1;
23     }
24     return ans;
25 }
26 int main()
27 {
28     scanf("%d%d",&n,&k);
29     for(int i=1;i<=n;++i)fa[i]=i;
30     for(int i=1;i<n;++i)
31     {
32         int u,v,w;
33         scanf("%d%d%d",&u,&v,&w);
34         if(!w)
35         {
36             if(find(u)!=find(v))fa[find(u)]=find(v);
37         }
38     }
39     ll ans=fastpow(n,k);
40     for(int i=1;i<=n;++i)sz[find(i)]++;
41     for(int i=1;i<=n;++i)if(find(i)==i)
42     {
43         ans=(ans-fastpow(sz[i],k)+mod)%mod;
44     }
45     printf("%I64d
",ans);
46 }
View Code

 

F.

题解:考虑转化条件,就是p[i]<=inc[j]<=s[i]

            b[i]+p[i]<=pref[j]+inc[j]

            b[i]-p[i]>=pref[j]-inc[j]

然后第一个不等式用扫描线维护,后两个看成平面上的点坐标

kdtree维护矩形

技术图片
  1 #include<bits/stdc++.h>
  2 #define inf 2000000009
  3 #define ll long long
  4 #define maxn 200005
  5 using namespace std;
  6 int now;
  7 struct point
  8 {
  9     int d[2],minv[2],maxv[2],l,r;
 10     int v,sumv,size;
 11     void clear(){d[0]=d[1]=minv[0]=minv[1]=maxv[0]=maxv[1]=l=r=v=sumv=0;}
 12 };
 13 bool operator ==(point a,point b){return a.d[0]==b.d[0]&&a.d[1]==b.d[1];}
 14 bool operator <(point a,point b)
 15 {
 16     if(a.d[now]==b.d[now])return a.d[now^1]<b.d[now^1]; 
 17     return a.d[now]<b.d[now];
 18 }
 19 int rt,cnt;
 20 point t[maxn],a[maxn],p;
 21 bool in(point a,point b)
 22 {
 23     return a.minv[0]<=b.minv[0]&&b.maxv[0]<=a.maxv[0]&&a.minv[1]<=b.minv[1]&&b.maxv[1]<=a.maxv[1];
 24 }
 25 bool out(point a,point b)
 26 {
 27     return a.maxv[0]<b.minv[0]||a.minv[0]>b.maxv[0]||a.maxv[1]<b.minv[1]||a.minv[1]>b.maxv[1];
 28 }
 29 void pushup(int x)
 30 {
 31     int l=t[x].l,r=t[x].r;
 32     t[x].size=t[l].size+t[r].size+1; 
 33     t[x].sumv=t[l].sumv+t[r].sumv+t[x].v;
 34     for(int i=0;i<2;i++)
 35     {
 36         t[x].minv[i]=t[x].maxv[i]=t[x].d[i];
 37         if(l)t[x].minv[i]=min(t[x].minv[i],t[l].minv[i]),t[x].maxv[i]=max(t[x].maxv[i],t[l].maxv[i]);
 38         if(r)t[x].minv[i]=min(t[x].minv[i],t[r].minv[i]),t[x].maxv[i]=max(t[x].maxv[i],t[r].maxv[i]);
 39     }
 40 }
 41 point tmp;
 42 void add(int x,int v,bool f)
 43 {
 44     if(!x)return;
 45     if(t[x]==p)
 46     {
 47         t[x].v+=v;
 48         pushup(x);
 49         return;
 50     }
 51     now=f;
 52     if(p<t[x])add(t[x].l,v,f^1);
 53     else add(t[x].r,v,f^1);
 54     pushup(x);
 55 }
 56 int query(int x)
 57 {
 58     int ans=0;
 59     if(!x)return 0;
 60     if(in(p,t[x]))
 61     {
 62         return t[x].sumv;
 63     }
 64     if(out(p,t[x]))return 0;
 65     tmp.clear();
 66     tmp.minv[0]=tmp.maxv[0]=t[x].d[0];
 67     tmp.minv[1]=tmp.maxv[1]=t[x].d[1];
 68     if(in(p,tmp))ans+=t[x].v;
 69     ans+=query(t[x].l)+query(t[x].r);
 70     pushup(x);
 71     return ans;
 72 }
 73 int rebuild(int l,int r,bool f)
 74 {
 75     if(l>r)return 0;
 76     int mid=(l+r)/2;now=f;
 77     nth_element(a+l,a+mid,a+r+1);
 78     t[mid]=a[mid];
 79     t[mid].l=rebuild(l,mid-1,f^1);
 80     t[mid].r=rebuild(mid+1,r,f^1);
 81     pushup(mid);
 82     return mid;
 83 }
 84 int n,m;
 85 struct data
 86 {
 87     int p,s,b;
 88     int inc,pref;
 89 }d[maxn*2];
 90 struct data2
 91 {
 92     int id,tp,x;
 93 }dd[maxn*3];
 94 bool operator < (data2 A,data2 B)
 95 {
 96     if(A.x==B.x)return A.tp>B.tp;
 97     return A.x<B.x;
 98 }
 99 bool cmp(point A,point B)
100 {
101     if(A.d[0]==B.d[0])return A.d[1]<B.d[1];
102     return A.d[0]<B.d[0];
103 }
104 int ans[maxn];
105 int main()
106 {
107    scanf("%d%d",&n,&m);
108    for(int i=1;i<=n;++i)scanf("%d",&d[i].p);
109    for(int i=1;i<=n;++i)scanf("%d",&d[i].s);
110    for(int i=1;i<=n;++i)scanf("%d",&d[i].b);
111    for(int i=1;i<=n;++i)
112    {
113            a[i].clear();
114         a[i].d[0]=d[i].b+d[i].p;
115         a[i].d[1]=d[i].b-d[i].p;
116    }
117    sort(a+1,a+n+1,cmp);
118    int D=unique(a+1,a+n+1)-a-1;
119    rt=rebuild(1,D,0);
120    for(int i=n+1;i<=n+m;++i)scanf("%d",&d[i].inc);
121    for(int i=n+1;i<=n+m;++i)scanf("%d",&d[i].pref);
122    int CNT=0;
123    for(int i=1;i<=m;++i)dd[++CNT].id=i+n,dd[CNT].tp=0,dd[CNT].x=d[i+n].inc;
124    for(int i=1;i<=n;++i)
125    {
126            dd[++CNT].id=i;dd[CNT].tp=1;dd[CNT].x=d[i].p;
127            dd[++CNT].id=i;dd[CNT].tp=-1;dd[CNT].x=d[i].s;
128    }
129    sort(dd+1,dd+CNT+1);
130    for(int i=1;i<=CNT;++i)
131    {
132         if(dd[i].tp)
133         {
134             p.clear();
135             int t=dd[i].id;
136             p.d[0]=p.minv[0]=p.maxv[0]=d[t].b+d[t].p;
137             p.d[1]=p.minv[1]=p.maxv[1]=d[t].b-d[t].p;
138             add(rt,dd[i].tp,0);
139         }
140         else
141         {
142             p.clear();
143             int t=dd[i].id;
144             p.maxv[0]=d[t].inc+d[t].pref;
145             p.minv[0]=-inf;
146             p.maxv[1]=inf;
147             p.minv[1]=d[t].pref-d[t].inc;
148             ans[t-n]=query(rt);
149         }
150    }
151    for(int i=1;i<=m;++i)printf("%d ",ans[i]);
152    return 0;
153 }
View Code

 

以上是关于codeforces #548 div2的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

Codeforces Round #393 div2

Codeforces Round #326 div2

Codeforces Round #564(div2)

Codeforces Round #394 div2

C. Edgy Trees Codeforces Round #548 (Div. 2) 并查集求连通块