CF1495E Qingshan and Daniel
CF1495E Qingshan and Daniel
前言
我真的是欲哭无泪。。。
这场CD我当时卡住了,我万万没想到这E这么傻逼。。。
E Qingshan and Daniel
链接
https://codeforces.ml/contest/1495/problem/E
题意
n个人围成一圈打牌,1右边是2,2右边是3...n右边是1,n个人分成2个阵营,第i个人有\(a_i\)张牌。刚开始第1个人出牌,然后当第i个人出牌后,跟i不同阵营的在i右侧最近的人出一张牌,然后不停进行下去,直到某一阵营没有牌,要求算出每个人出了几张牌。\(1\leq n \leq 5e6,1\leq a_i \leq 1e9+7\) 。
题解
如果与1相同阵营的牌的总数小于另一阵营的总数,则跟1同阵营的肯定出了\(a_i\)张。
然后这些肯定会出的牌要向右贪心的找另一阵营的人来出牌抵消,向右方向贪心转两圈即可。
然后是1阵营的排数更多的情况,分两种情况讨论。
如果另一阵营没牌,那么一共就1出了一张牌。
否则先让1出牌,此时先手的阵营换成对面。题目就又编程先手方牌数更少的情况,按照之前的方法贪心即可。
\(Code\)
#include <bits/stdc++.h>
#define LL long long
#define LD long double
using namespace std;
const LL P=1e9+7;
const int N=3e5+10;
const int INF=1e9;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
void pls(LL &x,LL y){
x+=y;if(x>=P)x-=P;
}
int n,m;
LL seed=0;
LL base=0;
LL rnd(){
LL ret=seed;
seed=(seed*base+233)%P;
return ret;
}
int p[200005];
LL k[200005],b[200005],w[200005];
LL t[5000005],a[5000005];
LL ans[5000005];
void MAIN(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
scanf("%d%lld%lld%lld",&p[i],&k[i],&b[i],&w[i]);
}
p[0]=0;
for(int i=1;i<=m;++i){
seed=b[i];
base=w[i];
for(int j=p[i-1]+1;j<=p[i];++j){
t[j]=(rnd()%2)+1;
a[j]=(rnd()%k[i])+1;
}
}
LL sum1=0,sum2=0;
for(int i=1;i<=n;++i){
ans[i]=0;
if(t[i]==t[1]){
sum1+=a[i];
}
else{
sum2+=a[i];
}
}
int S=1;
if(sum1>sum2){
ans[1]=1;--sum1;--a[1];
if(sum2){
for(int i=2;i<=n;++i) if(t[i]!=t[1]){
S=i;break;
}
}
swap(sum1,sum2);
}
LL x=0,y;
if(sum1){
for(int i=S;i<=n;++i){
if(t[i]==t[S]){
ans[i]+=a[i];
x+=a[i];
}
else{
y=min(a[i],x);
ans[i]+=y;
x-=y;
a[i]-=y;
}
}
for(int i=1;i<S;++i){
if(t[i]==t[S]){
ans[i]+=a[i];
x+=a[i];
}
else{
y=min(a[i],x);
ans[i]+=y;
x-=y;
a[i]-=y;
}
}
for(int i=S;i<=n;++i){
if(t[i]!=t[S]){
y=min(a[i],x);
ans[i]+=y;
x-=y;
a[i]-=y;
}
}
for(int i=1;i<S;++i){
if(t[i]!=t[S]){
y=min(a[i],x);
ans[i]+=y;
x-=y;
a[i]-=y;
}
}
}
LL res=1;
for(int i=1;i<=n;++i){
x=ans[i];
y=(LL)i*i;
x=x^y;
++x;
x=x%P;
res=res*x%P;
}
printf("%lld\n",res);
return;
}
int main(){
int ttt=1;
while(ttt--) MAIN();
return 0;
}