感受題解解釋的很牽強啊……仍是打表找規律比較靠譜node
對於每一個人,它構造了一個指望函數$f(x)$,設它的跟班個數爲$cnt[x]$,那麼令$f(x)=2^{cnt[x]}-1$(??鬼知道爲何要等於這個)ios
而後再定義當前局面的指望函數爲每一個人指望函數之和。c++
而後你會發現每次猜拳後局面指望函數變化量都是1git
那麼指望步數其實就是終止局面指望函數值-初始局面指望函數值函數
$ans=2^{n-1}-1-\sum (2^{cnt[x]}-1)$this
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; ll qpow(ll a,ll b) { ll res=1; while(b) { if(b&1)res=res*a%mod; a=a*a%mod; b>>=1; } return res; } int n,a[100005],cnt[100005]; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); cnt[a[i]]++; } ll ans=qpow(2,n-1)-1;ans=(ans+mod)%mod; for(int i=1;i<=n;i++) ans-=qpow(2,cnt[i])-1,ans=(ans+mod)%mod; printf("%lld\n",ans); return 0; }
垃圾dp。考場上想麻煩了。kuku。spa
$dp[i][0/1]$表示前i個字符,已經/沒有出現過Triple Kill的方案數指針
轉移就好了……excel
#include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef long long ll; const ll mod=1e9+7; int T,n; ll m,dp[100005][2]; void work() { scanf("%d%lld",&n,&m); if(n<3){puts("0");return ;} memset(dp,0,sizeof(dp)); dp[1][0]=m;dp[2][0]=m*m%mod;dp[3][0]=m*m%mod*m%mod;dp[3][0]=(dp[3][0]-m+mod)%mod;dp[3][1]=m; for(int i=4;i<=n;i++) { (dp[i][0]+=dp[i-1][0]*(m-1)%mod)%=mod; (dp[i][0]+=dp[i-2][0]*(m-1)%mod)%=mod; (dp[i][1]+=dp[i-1][1]*(m-1)%mod)%=mod; (dp[i][1]+=dp[i-2][1]*(m-1)%mod)%=mod; (dp[i][1]+=dp[i-3][0]*(m-1)%mod)%=mod; //cout<<i<<' '<<dp[i][0]<<' '<<dp[i][1]<<endl; } printf("%lld\n",dp[n][1]); } int main() { freopen("flower.in","r",stdin); freopen("flower.out","w",stdout); scanf("%d",&T); while(T--)work(); return 0; }
正解不會。閒的沒事自主研發了個指針二維線段樹的板子拿了個部分分。blog
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int base=1001,M=2002,inf=0x3f3f3f3f; int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } int maxx=-inf,minx=inf,maxy=-inf,miny=inf,ans; int n; struct node { node *ls,*rs; node *ys; int v; node() { ls=rs=NULL; v=0; } /*void down() { if(this->ls!=NULL)this->ls->v=this->v; if(this->rs!=NULL)this->rs->v=this->v; }*/ }; node *root; void judge(node *&k) { if(k==NULL)k=new node(); } void upy(node *&k,int l,int r,int x,int y,int xx,int yy,int val) { if(y<=l&&yy>=r) { k->v=val;return ; } int mid=l+r>>1; if(y<=mid) { judge(k->ls); upy(k->ls,l,mid,x,y,xx,yy,val); } if(yy>mid) { judge(k->rs); upy(k->rs,mid+1,r,x,y,xx,yy,val); } } void upx(node *&k,int l,int r,int x,int y,int xx,int yy,int val) { if(x<=l&&xx>=r) { judge(k->ys); upy(k->ys,1,M,x,y,xx,yy,val); return ; } int mid=l+r>>1; if(x<=mid) { judge(k->ls); upx(k->ls,l,mid,x,y,xx,yy,val); } if(xx>mid) { judge(k->rs); upx(k->rs,mid+1,r,x,y,xx,yy,val); } } void asky(node *&k,int l,int r,int x,int y) { ans=max(ans,k->v); if(l==r)return ; int mid=l+r>>1; if(y<=mid) { judge(k->ls); asky(k->ls,l,mid,x,y); } else { judge(k->rs); asky(k->rs,mid+1,r,x,y); } } void askx(node *&k,int l,int r,int x,int y) { judge(k->ys); asky(k->ys,1,M,x,y); if(l==r)return ; int mid=l+r>>1; if(x<=mid)judge(k->ls),askx(k->ls,l,mid,x,y); else judge(k->rs),askx(k->rs,mid+1,r,x,y); } int vis[100005]; #define F int main() { #ifdef F freopen("excel.in","r",stdin); freopen("excel.out","w",stdout); #endif n=read();root=new node(); for(int q=1;q<=n;q++) { int x=read()+base+1,y=read()+base+1,xx=read()+base,yy=read()+base; swap(x,y);swap(xx,yy); minx=min(minx,x);maxx=max(maxx,xx); miny=min(miny,y);maxy=max(maxy,yy); upx(root,1,M,x,y,xx,yy,q); } int cnt=1; for(int i=minx;i<=maxx;i++) { //puts(" "); for(int j=miny;j<=maxy;j++) { ans=0;askx(root,1,M,i,j); if(ans&&!vis[ans])vis[ans]=1,cnt++; //cout<<ans<<' '; } } printf("%d\n",cnt); return 0; }