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 
一开始想的尺取,就是想找到每个合法的区间然后按上面的算一遍,但是这样会漏下一些
举个比方
111111111111111001111111111101111111111100111111111001111111111111100
8
9
这组 头指针和尾指针只会找合法的尽量长的区间,但是我们还有一种把0拿过来的操作,需要一些合法的比较短的
目前还没想到怎么改....
*/ #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; }

 

posted @ 2018-08-31 10:11  一入OI深似海  阅读(245)  评论(0编辑  收藏  举报