[CTSC2017]金鑰
阿新 • • 發佈:2019-02-04
一個環 有 個位置, 選擇 個位置填上// 個 或 個
….題目太長了 自己查吧qwq
有一點很容易想到就是把 和 一個看成 一個看成 空位看成
然後列舉空位的位置為x 快速計算答案。
我們發現
對於 : 且 位置為 即可對答案有貢獻
對於 : 即可對答案有貢獻
整理得:
可以資料結構維護這個拿到部分分。
然後我們發現 每個相鄰的只差。我們可以暴力記錄下所有的 然後每次計算答案。
整體複雜度 注意思考一下修改列舉過的陣列值時應該新開陣列記錄。 即。
#include <bits/stdc++.h>
using namespace std;
const int base=10000000;
int sum[20000010],p[20000010],buc[20000010],bucc[20000010];
int seed,n,k,S;
int getrand(){
seed=((seed*12321)^9999)%32768;
return seed;
}
void generateData(){
scanf("%d%d%d",&k,&seed,&S);
int t=0;
n=k*2+1;
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++)
{
p[i]=(getrand()/128)%2;
t+=p[i];
}
int i=1;
while(t>k)
{
while(p[i]==0)
i++;
p[i]=0;
t--;
}
while(t<k){
while(p[i]==1)
i++;
p[i]=1;
t++;
}
}
int ans=0,pos,pos2,pos3;
//sum[i]>sum[x]
//sum[n]-sum[x]+sum[i]>0
//sum[i]>sum[x]+1
//sum[]
int main(){
generateData();
for(int i=1;i<=n;i++)sum[i]=p[i]?sum[i-1]+1:sum[i-1]-1;
for(int i=1;i<=n;i++){
if(p[i]){
buc[sum[i]+base]++;
}
}
for(int i=2;i<=n;i++)
if(sum[i]>sum[1]&&p[i])ans++;
if(!p[1]&&ans==0)pos=1;
if(!p[1]&&ans==S)pos2=1;
if(p[1])buc[sum[1]+base]--,buc[sum[1]+base-1]++;
int now=sum[1]+base+1;
// puts("qwq");
for(int x=2;x<=n;x++){
// cout<<ans<<endl;
if(p[x]){
ans-=buc[now++];
buc[sum[x]+base]--,buc[sum[x]+base-1]++;
}
else {
ans+=buc[--now];
if(ans==0)pos=x;
else if(ans==S)pos2=x;
}
}
// cout<<ans<<endl;
//puts("qaq");
// sum[i]>sum[x]
// sum[n]-sum[x]+sum[i]>0
// sum[i]>sum[x]-1
ans=0;
memset(buc,0,sizeof(buc));
for(int i=1;i<=n;i++)sum[i]=p[i]?sum[i-1]-1:sum[i-1]+1;
for(int i=1;i<=n;i++){
if(!p[i]){
buc[sum[i]+base]++;
}
}
for(int i=2;i<=n;i++)
if(sum[i]>sum[1]&&(!p[i]))ans++;
if(!p[1]&&ans==S)pos3=1;
// for(int i=1;i<=20000005;i++)bucc[i]=buc[i];
// if(!p[1])bucc[sum[1]+base]--,bucc[sum[1]+base+1]++;
now=sum[1]+base+1;
// cout<<ans; 1 2 3 4 3 2 1 0 -1 0 1
for(int x=2;x<=n;x++){
// cout<<ans<<endl;
if(!p[x]){
ans-=buc[now++];
if(!p[x-1])buc[sum[x-1]+base]--,buc[sum[x-1]+base+1]++;
// bucc[sum[x]+base]--,bucc[sum[x]+base+1]++;
if(ans==S)pos3=x;
}
else {
ans+=buc[--now];
if(!p[x-1])buc[sum[x-1]+base]--,buc[sum[x-1]+base+1]++;
}
}
cout<<pos<<endl<<pos2<<endl<<pos3<<endl;
return 0;
}
//0 0 0 0 1 1 1 1 1 0 0