8.30 "我什么都不会"

/*
抢名额第一场 GG
"我什么都不会阿"
这场磕死在E题了
按说应该能想到费马小定理 毕竟p is a prime
别的队都过了 大家都比较熟悉的就只有这一个
然后还有I题一开始尺取有个思路,然后很快找出bug
这时没换思路而是补了一下这个bug 就加个if
然后疯狂wa4 策略不对
其实wa个几发就该意识到思路有问题了
但是还是一直怼 不合理
积累经验了就 下场注意 
*/
/*
先看E题吧  打表猜测答案2^(2^n-n)%p 
指数 不能mod 根据费马小定理 2^(p-1)%p==1
每p-1个2乘起来对答案没有贡献 所以指数%p-1
另外p==2的时候 2和p不互质 特判一下 
*/
#include<iostream>
#define ll long long
using namespace std;
ll n,k,p,ans;
ll Mi(ll a,ll b,ll c){
    if(b==0)return 1;ll res=Mi(a,b/2,c);
    res=res*res%c;if(b&1)res=res*a%c;return res;
}
int main(){
    cin>>n>>k>>p;ans=Mi(2,(Mi(2,n,p-1)-n%(p-1)+p-1)%(p-1),p);
    if(k==0)ans=(ans-1+p)%p;if(p==2)ans=0+(k==0);cout<<ans<<endl;return 0;
}
/*
I题 根据题目的指引 应该是在线做 每次严格On
On的算法无非就是贪心尺取和单调队列
这题对于每个区间答案是r+l-1-(p[r]-p[l-1])+k-(p[r]-p[l-1])
pi是前缀1的个数 化简后 r-2p[r]+1+k+2p[l-1]-l
枚举r 维护合法的l的最优值 合法的l必须有 p[r]-p[l-1]<=k 
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 1000010
using namespace std;
int n,m,q[maxn],p[maxn],hea,tai,ans;
char s[maxn];
int main(){
    scanf("%s%d",s+1,&m);n=strlen(s+1);
    for(int i=1;i<=n;i++)p[i]=p[i-1]+s[i]-'0';
    while(m--){
        int k;scanf("%d",&k);hea=tai=0;ans=0;
        for(int i=1;i<=n;i++){
            while(hea<tai&&2*p[q[tai]-1]-q[tai]<=2*p[i-1]-i)tai--;
            q[++tai]=i;
            while(hea<tai&&p[i]-p[q[hea+1]]>k)hea++;
            ans=max(ans,i-2*p[i]+1+k-q[hea+1]+2*p[q[hea+1]-1]); 
        }
        printf("%d\n",min(ans,n-p[n]));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yanlifneg/p/9564207.html