文章目錄
2019-9-15 雜題選講
題目
CF1174E Ehab and the Expected GCD Problem
這題給人的大概感覺就是,前綴是不增的,那麼我們既然想要前綴儘量不同,我們必然希望它慢慢地下降,每次降一丟丟,那麼我每次就只允許它降一半就是最優的咯,於是這就有了的結論的感性理解版。但是第一個數並不一定是的次冪,有可能帶一個,因爲乘最後一個時,如果加個不會爆,加個也是可以的。於是第一個數就是,於是上計數即可
[ZJOI2019]線段樹
恭喜此題榮獲本週的鎮題之寶
link
震驚!天天打線段樹的人竟不知線段樹中有這五種點
這題的大致思路如下。首先每棵樹的編號(相對順序)是不影響答案的,我們只需要知道每次複製了一遍,新的,舊的不動。那麼我們設計狀態表示i次操作後有多少個點有,我們將點分類之後分別寫出方程,發現還需維護一個表示次操作後有多少個點到的路徑上沒有,來輔助計算,這些線段樹上的點經過分類後可以發現,有的是每次個數不超過級別,有的則是一棵小子樹,那麼前者暴力修改,後者用正常的即可
CF1197D Yet Another Subarray Problem
這題就是推式子的時候令即可,由於m很小從左往右掃的時候維護前綴最小值時按%m分類即可
P4965 薇爾莉特的打字機
這題代碼但是思路。我們先考慮在樹上分析這個問題
- 若一個把可以到達的點上做一個標記,那麼加入一個字符時所有的標記點都拓展出一個新點,並且舊點仍然保留標記,那麼我們就維護好表示擁有邊的節點個數即可快速轉移
- 若收到一個退格,多出來的答案就只有一個,就是原串從開始到這個退格之前的串,於是,但是退格了之後相當於某個點向上走了一步,那麼這個位置的點雖然已經有了一個標記,但是我們要把它當作兩個點,於是,然後這題就沒了
P2405 non天平
這題的思維難度不高,必然首先把物品轉成進制,由於我們兩邊都能放砝碼,相當於我們可以用一個大砝碼減去一些小法碼,從而得到原本用一些小砝碼稱出來的東西,但是這個相減的操作必定出現在大小相鄰的兩個砝碼之間,而且必定大砝碼只會用一個,除非我是傻的,那麼從高到低即可
代碼
CF1174E Ehab and the Expected GCD Problem代碼
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register int j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int mod=1e9+7;
int n,dp[N][21][2],lim=1,lg=0,ans;
int er[N],san[N];
inline int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
inline int CAL(int x,int y)
{
if (x<0||y<0) return 0;
if (!er[x]||!san[y]) return 0;
int ret=n/(er[x]*san[y]);
return ret;
}
int main()
{
mem(dp,0);
n=read();
while ((lim<<1)<=n) lim<<=1,lg++;
er[0]=1;
FOR(i,1,lg) er[i]=1LL*er[i-1]*2%mod;
san[0]=1;
for (register int i=1;san[i-1]*3<=n;i++) san[i]=1LL*san[i-1]*3%mod;
dp[1][lg][0]=1;
if (er[lg-1]*3<=n) dp[1][lg-1][1]=1;
FOR(i,2,n)
FOR(x,0,lg)
{
dp[i][x][0]=(1LL*dp[i-1][x][0]*(CAL(x,0)-i+1)%mod+1LL*dp[i-1][x][1]*(CAL(x,0)-CAL(x,1))%mod+1LL*dp[i-1][x+1][0]*(CAL(x,0)-CAL(x+1,0))%mod)%mod;
dp[i][x][1]=(1LL*dp[i-1][x][1]*(CAL(x,1)-i+1)%mod+1LL*dp[i-1][x+1][1]*(CAL(x,1)-CAL(x+1,1))%mod)%mod;
}
ans=dp[n][0][0];
write(ans);
return 0;
}
[ZJOI2019]線段樹代碼
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register int j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int mod=998244353;
int n,m,cnt=1,opt,tmp1,tmp2,ans[N];
int sum[N<<2],f[N<<2],g[N<<2],tag_f[N<<2],tag_g[N<<2];
inline int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
inline void up(int p)
{
sum[p]=(1LL*sum[p<<1]+sum[p<<1|1]+f[p])%mod;
return;
}
inline void bd(int p,int l,int r)
{
sum[p]=f[p]=0;
g[p]=1;
tag_f[p]=tag_g[p]=1;
if (l==r) return;
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
bd(ls,l,mid);
bd(rs,mid+1,r);
up(p);
return;
}
inline void mul_f(int p,int v)
{
tag_f[p]=1LL*tag_f[p]*v%mod;
sum[p]=1LL*sum[p]*v%mod;
f[p]=1LL*f[p]*v%mod;
return;
}
inline void mul_g(int p,int v)
{
tag_g[p]=1LL*tag_g[p]*v%mod;
g[p]=1LL*g[p]*v%mod;
return;
}
inline void down(int p)
{
int ls=p<<1,rs=p<<1|1;
if (tag_f[p]!=1)
{
mul_f(ls,tag_f[p]);
mul_f(rs,tag_f[p]);
tag_f[p]=1;
}
if (tag_g[p]!=1)
{
mul_g(ls,tag_g[p]);
mul_g(rs,tag_g[p]);
tag_g[p]=1;
}
return;
}
inline void md(int p,int l,int r,int L,int R)
{
down(p);
int mid=(l+r)>>1,ls=p<<1,rs=p<<1|1;
if (L<=l&&r<=R)
{
mul_f(ls,2);mul_f(rs,2);
f[p]=(1LL*f[p]+cnt)%mod;
up(p);
return;
}
g[p]=(1LL*g[p]+cnt)%mod;
if (R<=mid)
{
md(ls,l,mid,L,R);
down(rs);
f[rs]=(1LL*f[rs]+cnt-g[rs]+mod)%mod;
g[rs]=(1LL*g[rs]+g[rs])%mod;
mul_g(rs<<1,2);mul_g(rs<<1|1,2);
mul_f(rs<<1,2);mul_f(rs<<1|1,2);
up(rs);
}
else if (L>mid)
{
md(rs,mid+1,r,L,R);
down(ls);
f[ls]=(1LL*f[ls]+cnt-g[ls]+mod)%mod;
g[ls]=(1LL*g[ls]+g[ls])%mod;
mul_g(ls<<1,2);mul_g(ls<<1|1,2);
mul_f(ls<<1,2);mul_f(ls<<1|1,2);
up(ls);
}
else
{
md(ls,l,mid,L,R);
md(rs,mid+1,r,L,R);
}
up(p);
return;
}
int main()
{
// freopen("data.in","r",stdin);
n=read(),m=read();
bd(1,1,n);
FOR(i,1,m)
{
opt=read();
if (opt==1) tmp1=read(),tmp2=read();
if (opt==1) md(1,1,n,tmp1,tmp2),cnt=(1LL*cnt+cnt)%mod;
else ans[++ans[0]]=sum[1];
}
FOR(i,1,ans[0]) write(ans[i]),putchar('\n');
return 0;
}
CF1197D Yet Another Subarray Problem代碼
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register ll i=(a);i<=(b);i++)
#define For(i,a,b) for (register ll i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register ll j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const ll N=3e5+5;
const ll inf=1e17;
ll n,m,k,a[N],s[N],mn[20],r[N],tmp,ans=0;
inline ll read()
{
ll x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(ll x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
int main()
{
n=read(),m=read(),k=read();
FOR(i,1,m-1) mn[i]=inf;
FOR(i,1,n) a[i]=read();
FOR(i,1,n) s[i]=s[i-1]+a[i];
FOR(i,1,n) r[i]=s[i]-k*(i/m);
FOR(i,1,n)
{
tmp=i%m;
FOR(j,0,m-1) ans=max(ans,r[i]-mn[j]-k*((i%m-j+m-1)/m));
mn[tmp]=min(mn[tmp],r[i]);
}
write(ans);
return 0;
}
P4965 薇爾莉特的打字機代碼
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register int j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const int N=5e6+5;
const int mod=19260817;
int n,m,ans=1,rest,F[100];
char A[N],B[N];
inline int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
inline void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
int main()
{
n=read(),m=read();
rest=n;
scanf("%s",A+1);
scanf("%s",B+1);
FOR(i,1,m)
{
int c=B[i]-'A'+1;
if (1<=c&&c<=26)
{
int f=F[c];
F[c]=ans;
ans=(1LL*(ans<<1)-f+mod)%mod;
}
else
{
if (!rest) continue;
ans++;
ans%=mod;
F[A[rest]-'A'+1]++;
F[A[rest]-'A'+1]%=mod;
rest--;
}
}
write(ans);
return 0;
}
P2405 non天平代碼
#include<bits/stdc++.h>
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(u) for (register int j=f[u];j!=-1;j=nxt[j])
using namespace std;
typedef long long ll;
const int N=2e6+5;
int n,s[N],tmps[N],len=0,r[N],dp[N][2],ans;
inline void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
return;
}
inline int get_yu()
{
int ret=0;
FOR(i,1,len)
{
ret=(ret<<1)+(ret<<3)+s[i];
ret%=n;
}
return ret;
}
inline void devide()
{
int now=0,tmplen=0,ready=0;
FOR(i,1,len) tmps[i]=0;
FOR(i,1,len)
{
now=(now<<1)+(now<<3)+s[i];
if (now>=n) ready=1;
if (ready)
{
tmps[++tmplen]=now/n;
now%=n;
}
}
len=tmplen;
FOR(i,1,len) s[i]=tmps[i];
return;
}
int main()
{
// freopen("testdata (1).in","r",stdin);
char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') s[++len]=c-'0',c=getchar();
scanf("%d",&n);
if (n==1) {FOR(i,1,len) write(s[i]);exit(0);}
while (len)
{
r[++r[0]]=get_yu();
devide();
}
dp[r[0]+1][1]=1;
For(i,r[0],1)
{
dp[i][0]=min(dp[i+1][0]+r[i],dp[i+1][1]+n-r[i]);
dp[i][1]=min(dp[i+1][0]+r[i]+1,dp[i+1][1]+n-r[i]-1);
}
ans=dp[1][0];
write(ans);
return 0;
}