Codeforces Round #539 Div. 1
A:即求长度为偶数的异或和为0的区间个数,对前缀异或和用桶记录即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N],cnt[1<<20][2];
ll ans;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=a[i-1]^read();
cnt[0][0]=1;
for (int i=1;i<=n;i++)
{
ans=ans+cnt[a[i]][i&1];
cnt[a[i]][i&1]++;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
B:显然如果有解,答案一定不大于2,因为原串是回文串,找到第一个不是回文串的前缀和对其对应后缀切掉并交换即可。无解直接判断是否字母都相同或只有最中间字母不同。然后只需要check是否为1,暴力枚举切割点暴力判断即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 5010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n;
char s[N],a[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
scanf("%s",s+1);n=strlen(s+1);
if (n==1) {cout<<"Impossible";return 0;}
bool flag=1;
for (int i=2;i<=n;i++) if (s[i]!=s[1]) {flag=0;break;}
if (flag) {cout<<"Impossible";return 0;}
if (n&1)
{
bool flag=1;
for (int i=2;i<=n;i++) if (s[i]!=s[1]&&i!=(n+1)/2) {flag=0;break;}
if (flag) {cout<<"Impossible";return 0;}
}
for (int i=1;i<n;i++)
{
for (int j=1;j<=n-i;j++) a[j]=s[j+i];
for (int j=n-i+1;j<=n;j++) a[j]=s[j-(n-i)];
bool flag=1;
for (int j=1;j<=n;j++) if (a[j]!=a[n-j+1]) {flag=0;break;}
if (!flag) continue;
for (int j=1;j<=n;j++) if (a[j]!=s[j]) {cout<<1;return 0;}
}
cout<<2;
return 0;
//NOTICE LONG LONG!!!!!
}
D:显然枚举两点路径上有多少个点,选出这些点并排列,给路径上每条边插板分配权值,剩余边权值任意取。只剩下一个问题,就是如何计算固定这条路径后,树的形态个数。考虑将这条边缩点,一条边连接某两个点的方案数是1,而连接某个点和这条链的方案数则是其链长。将链长作为这个点的权值,其余点权值为1,于是我们要统计的东西相当于缩点后每棵树的所有点权值度数之积的和。注意到出现了度数,考虑prufer序列。序列中每个点出现次数=其度数-1,并且由于要统计所有树,每种对应的prufer序列都存在。这样由分配律可得方案数即为(i+1)*nn-2-i,其中i为路径上点的个数。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1000010
#define P 1000000007
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a,b,fac[N],inv[N],ans;
int ksm(int a,int k)
{
int s=1;
for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
return s;
}
int C(int n,int m){if (m>n) return 0;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read(),m=read();read(),read();
fac[0]=1;for (int i=1;i<=N-10;i++) fac[i]=1ll*fac[i-1]*i%P;
inv[0]=inv[1]=1;for (int i=2;i<=N-10;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
for (int i=1;i<=N-10;i++) inv[i]=1ll*inv[i-1]*inv[i]%P;
for (int i=1;i<n;i++)
{
int x;if (i==n-1) x=1;else x=1ll*(i+1)*ksm(n,n-2-i)%P;
x=1ll*x*C(m-1,i-1)%P*C(n-2,i-1)%P*ksm(m,n-i-1)%P*fac[i-1]%P;
ans=(ans+x)%P;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
E:傻逼题,要是先开E而不是C说不定就码完了。对模数的质因子分别记录次数即可,线段树瞎维护。质因子的次幂可以预处理一下,略卡常。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,P,a[N],q,L[N<<2],R[N<<2],ans[N<<2],p[12],u[12][2][1000010],cnt;
ll lazy[N<<2][12];
int ksm(int a,ll k)
{
return 1ll*u[a][0][k%1000000]*u[a][1][k/1000000]%P;
}
void exgcd(int &x,int &y,int a,int b)
{
if (b==0)
{
x=1,y=0;
return;
}
exgcd(x,y,b,a%b);
int t=x;x=y;y=t-a/b*x;
}
int inv(int a)
{
int x,y;
exgcd(x,y,a,P);
return (x%P+P)%P;
}
void up(int k){ans[k]=(ans[k<<1]+ans[k<<1|1])%P;}
void update(int k)
{
ans[k]=lazy[k][0];
for (int i=1;i<=cnt;i++) ans[k]=1ll*ans[k]*ksm(i,lazy[k][i])%P;
}
void down(int k,int i)
{
lazy[k<<1][i]+=lazy[k][i],lazy[k<<1|1][i]+=lazy[k][i];
ans[k<<1]=1ll*ans[k<<1]*ksm(i,lazy[k][i])%P,ans[k<<1|1]=1ll*ans[k<<1|1]*ksm(i,lazy[k][i])%P;
lazy[k][i]=0;
}
void down(int k)
{
lazy[k<<1][0]=1ll*lazy[k<<1][0]*lazy[k][0]%P;
lazy[k<<1|1][0]=1ll*lazy[k<<1|1][0]*lazy[k][0]%P;
ans[k<<1]=1ll*ans[k<<1]*lazy[k][0]%P;
ans[k<<1|1]=1ll*ans[k<<1|1]*lazy[k][0]%P;
lazy[k][0]=1;
for (int i=1;i<=cnt;i++)
down(k,i);
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;lazy[k][0]=1;
if (l==r)
{
ans[k]=lazy[k][0]=a[l];ans[k]%=P;
for (int i=1;i<=cnt;i++)
while (lazy[k][0]%p[i]==0)
lazy[k][0]/=p[i],lazy[k][i]++;
return;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k);
}
void add(int k,int l,int r,int i,int x,int u)
{
if (L[k]==l&&R[k]==r) {ans[k]=1ll*ans[k]*u%P;lazy[k][i]+=x;return;}
down(k,i);
int mid=L[k]+R[k]>>1;
if (r<=mid) add(k<<1,l,r,i,x,u);
else if (l>mid) add(k<<1|1,l,r,i,x,u);
else add(k<<1,l,mid,i,x,u),add(k<<1|1,mid+1,r,i,x,u);
up(k);
}
void mul(int k,int l,int r,int x)
{
if (L[k]==l&&R[k]==r) {ans[k]=1ll*ans[k]*x%P;lazy[k][0]=1ll*lazy[k][0]*x%P;return;}
down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) mul(k<<1,l,r,x);
else if (l>mid) mul(k<<1|1,l,r,x);
else mul(k<<1,l,mid,x),mul(k<<1|1,mid+1,r,x);
up(k);
}
void add(int k,int p,int i,int x)
{
if (L[k]==R[k]) {lazy[k][i]+=x;update(k);return;}
down(k,i);
int mid=L[k]+R[k]>>1;
if (p<=mid) add(k<<1,p,i,x);else add(k<<1|1,p,i,x);
up(k);
}
void mul(int k,int p,int x)
{
if (L[k]==R[k]) {lazy[k][0]=1ll*lazy[k][0]*x%P;update(k);return;}
down(k);
int mid=L[k]+R[k]>>1;
if (p<=mid) mul(k<<1,p,x);else mul(k<<1|1,p,x);
up(k);
}
int query(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return ans[k];
down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) return query(k<<1,l,r);
else if (l>mid) return query(k<<1|1,l,r);
else return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%P;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("e.in","r",stdin);
freopen("e.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read(),P=read();
int v=P;
for (int i=2;i*i<=v;i++)
if (v%i==0)
{
p[++cnt]=i;
while (v%i==0) v/=i;
}
if (v>1) p[++cnt]=v;
for (int i=1;i<=cnt;i++)
{
u[i][0][0]=1;
for (int j=1;j<=1000000;j++) u[i][0][j]=1ll*u[i][0][j-1]*p[i]%P;
u[i][1][0]=1;
for (int j=1;j<=1000000;j++) u[i][1][j]=1ll*u[i][1][j-1]*u[i][0][1000000]%P;
}
for (int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
q=read();
while (q--)
{
int op=read();
if (op==1)
{
int l=read(),r=read(),x=read();
for (int i=1;i<=cnt;i++)
{
int t=0;
while (x%p[i]==0) t++,x/=p[i];
if (t) add(1,l,r,i,t,ksm(i,t));
}
mul(1,l,r,x);
}
if (op==2)
{
int u=read(),x=read();
for (int i=1;i<=cnt;i++)
{
int t=0;
while (x%p[i]==0) t++,x/=p[i];
if (t) add(1,u,i,-t);
}
mul(1,u,inv(x));
}
if (op==3)
{
int l=read(),r=read();
printf("%d\n",query(1,l,r));
}
}
return 0;
//NOTICE LONG LONG!!!!!
}
C实在不想补。
result:rank 37 rating +142
F:先考虑一维情况怎么做。一些点在序列上连续相当于点数-边数(即相邻两点同时被选)=1,考虑在值域上不断移动右端点,用线段树维护每个后缀区间的点数-边数的值。由于每次只是对每个区间都增加该右端点,考虑该点对每个区间的影响,显然根据其相邻两数将值域分成几段,分别用线段树区间加即可。因为点数-边数>=1,维护区间最小值及个数即可统计答案。
拓展到二维,考虑使用同样的做法,但需要保证选出的点构成树。一个自然的想法是由于已经要求点数-边数=1,只要让选出的点构成连通块即可,但这个东西没有任何单调性。事实上注意到只要不形成环,加上点数-边数=1,也可以保证这是一棵树,而这个东西则是单调的。使用双指针,枚举右端点,找到最靠前的满足不构成环的左端点即可,可以LCT实现带删边并查集。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
#define lself tree[tree[k].fa].ch[0]
#define rself tree[tree[k].fa].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a[1010][1010],near[N][4];
ll ans;
struct data{int ch[2],fa,rev;
}tree[N];
void rev(int k){if (k) swap(lson,rson),tree[k].rev^=1;}
void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=0;}
int whichson(int k){return rself==k;}
bool isroot(int k){return lself!=k&&rself!=k;}
void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);}
void move(int k)
{
int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
tree[k].ch[!p]=fa,tree[fa].fa=k;
}
void splay(int k)
{
push(k);
while (!isroot(k))
{
int fa=tree[k].fa;
if (!isroot(fa))
if (whichson(fa)^whichson(k)) move(k);
else move(fa);
move(k);
}
}
void access(int k){for (int t=0;k;t=k,k=tree[k].fa) splay(k),tree[k].ch[1]=t;}
int findroot(int k){if (!k) return 0;access(k);splay(k);for (;lson;k=lson) down(k);splay(k);return k;}
void makeroot(int k){access(k),splay(k),rev(k);}
void link(int x,int y){makeroot(x);tree[x].fa=y;}
void cut(int x,int y){makeroot(x),access(y),splay(y);tree[y].ch[0]=tree[x].fa=0;}
int L[N<<2],R[N<<2],sum[N<<2],top[N<<2],lazy[N<<2];
void up(int k)
{
if (top[k<<1]==top[k<<1|1])
{
top[k]=top[k<<1];
sum[k]=sum[k<<1]+sum[k<<1|1];
}
else if (top[k<<1]<top[k<<1|1]) top[k]=top[k<<1],sum[k]=sum[k<<1];
else top[k]=top[k<<1|1],sum[k]=sum[k<<1|1];
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;
if (l==r) {sum[k]=1;return;}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k);
}
void Down(int k)
{
top[k<<1]+=lazy[k],top[k<<1|1]+=lazy[k];
lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k];
lazy[k]=0;
}
void add(int k,int l,int r,int op)
{
if (L[k]==l&&R[k]==r) {lazy[k]+=op;top[k]+=op;return;}
if (lazy[k]) Down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) add(k<<1,l,r,op);
else if (l>mid) add(k<<1|1,l,r,op);
else add(k<<1,l,mid,op),add(k<<1|1,mid+1,r,op);
up(k);
}
int query(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return (top[k]==1)*sum[k];
if (lazy[k]) Down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) return query(k<<1,l,r);
else if (l>mid) return query(k<<1|1,l,r);
else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
}
void print(int k,int l,int r)
{
if (L[k]==R[k]) {cout<<top[k]<<' ';return;}
if (lazy[k]) Down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) print(k<<1,l,r);
else if (l>mid) print(k<<1|1,l,r);
else print(k<<1,l,mid),print(k<<1|1,mid+1,r);
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("f.in","r",stdin);
freopen("f.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
a[i][j]=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
near[a[i][j]][0]=a[i-1][j];
near[a[i][j]][1]=a[i+1][j];
near[a[i][j]][2]=a[i][j-1];
near[a[i][j]][3]=a[i][j+1];
}
build(1,1,n*m);
int l=1;
for (int i=1;i<=n*m;i++)
{
bool flag;
do
{
flag=0;int u[5],t=0;u[t++]=findroot(i);
for (int j=0;j<4;j++) if (near[i][j]) u[t++]=findroot(near[i][j]);
for (int x=0;x<t;x++)
for (int y=x+1;y<t;y++)
if (u[x]==u[y]) {flag=1;break;}
if (!flag) break;
for (int j=0;j<4;j++) if (near[l][j]>=l&&near[l][j]<i) cut(l,near[l][j]);
l++;
}while (1);
add(1,l,i,1);
for (int j=0;j<4;j++)
if (near[i][j]>=l&&near[i][j]<=i)
link(i,near[i][j]),add(1,l,near[i][j],-1);
ans+=query(1,l,i);
//print(1,l,i);cout<<endl;
//cout<<l<<' '<<i<<' '<<ans<<endl;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
Codeforces Round #539 Div. 1的更多相关文章
- Codeforces Round #539 (Div. 2) - D. Sasha and One More Name(思维)
Problem Codeforces Round #539 (Div. 2) - D. Sasha and One More Name Time Limit: 1000 mSec Problem ...
- Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax(思维题)
Problem Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax Time Limit: 2000 mSec Problem ...
- Codeforces Round #539 (Div. 2)
Codeforces Round #539 (Div. 2) A - Sasha and His Trip #include<bits/stdc++.h> #include<iost ...
- Codeforces Round #539 (Div. 2) 题解
Codeforces Round #539 (Div. 2) 题目链接:https://codeforces.com/contest/1113 A. Sasha and His Trip 题意: n个 ...
- Codeforces Round #539 (Div. 2) D 思维
https://codeforces.com/contest/1113/problem/D 题意 将一个回文串切成一段一段,重新拼接,组成一个新的回文串,问最少切几刀 题解 首先无论奇偶串,最多只会切 ...
- Codeforces Round #539 (Div. 2) 异或 + dp
https://codeforces.com/contest/1113/problem/C 题意 一个n个数字的数组a[],求有多少对l,r满足\(sum[l,mid]=sum[mid+1,r]\), ...
- Codeforces Round #539 (Div. 2) C. Sasha and a Bit of Relax(前缀异或和)
转载自:https://blog.csdn.net/Charles_Zaqdt/article/details/87522917 题目链接:https://codeforces.com/contest ...
- Codeforces Round #539 (Div. 2) C Sasha and a Bit of Relax
题中意思显而易见,即求满足al⊕al+1⊕…⊕amid=amid+1⊕amid+2⊕…⊕ar且l到r的区间长为偶数的这样的数对(l,r)的个数. 若al⊕al+1⊕…⊕amid=amid+1⊕amid ...
- 20191031 Codeforces Round #539 (Div. 1) - Virtual Participation
这场怎么全是数据结构题...
随机推荐
- SpringBoot集成Shiro安全框架
跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...
- .net core实践系列之SSO-跨域实现
前言 接着上篇的<.net core实践系列之SSO-同域实现>,这次来聊聊SSO跨域的实现方式.这次虽说是.net core实践,但是核心点使用jquery居多. 建议看这篇文章的朋友可 ...
- WPF仿网易云音乐系列(一、左侧菜单栏:Expander+RadioButton)
1.简介 上一篇咱们说到,网易云音乐的左侧菜单栏可以通过Expander+RadioButton来实现,具体如何实现,咱们下面开始干: 首先来一张网易云音乐PC版原图(个人觉得PC版比UWP版左侧菜单 ...
- 04 Docker/基础设施 - DevOps之路
04 Docker/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi Docker是一个开源的引擎,可 ...
- python爬虫随笔-scrapy框架(1)——scrapy框架的安装和结构介绍
scrapy框架简介 Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试 ...
- pycharm 中 import requests 报错
一 , 使用Pycharm来抓取网页的时候,要导入requests模块,但是在pycharm中 import requests 报错. 原因: python中还没有安装requests库 解决办法: ...
- IOS 开发之-- textfield和textview,return键的改变,点击return键
IOS 开发之-- textfield和textview,return键的改变,点击return键 一,textfield的return键改变 方案1.改变键盘右下角的换行(enter)键为完成键,后 ...
- 消息队列queue
一.queue 在多线程编程中,程序的解耦往往是一个麻烦的问题,以及在socket网络编程中也会有这样的问题.recv 和send之间,如果服务端有消息,问题需要发送给客户端,而那边的recv 被主程 ...
- CopyOnWriteArrayList源码分析
基于jdk1.7源码 一.无锁容器 CopyOnWriteArrayList是JDK5中添加的新的容器,除此之外,还有CopyOnWriteArraySet.ConcurrentHahshMap和Co ...
- js压箱底的宝贝
框架的确好用, 不过他们也隐藏了JavaScript中丑陋的细节和DOM的运作机制. 如果你的目标是敢于自称"我懂JavaScript", 那么花时间学习框架无异于南辕北辙. 下面 ...