毕姥爷场
A
FWT
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int inv2=500000004;
ll power(ll n,ll p){
ll ans=1;
ll base=n;
while(p){
if(p&1)ans=ans*base%mod;
p>>=1;
base=base*base%mod;
}
return ans;
}
void fwt(ll a[],int len){
while(len!=(len&(-len)))len+=len&(-len);
for(int i=0;1<<i<len;i++){
for(int j=0;j<len;j+=(2<<i)){
for(int k=0;k<1<<i;k++){
ll l=a[j+k],r=a[j+(1<<i)+k];
a[j+k]=(l+r)%mod;
a[j+(1<<i)+k]=(l-r+mod)%mod;
}
}
}
}
void rfwt(ll a[],int len){
while(len!=(len&(-len)))len+=len&(-len);
int i=31-__builtin_clz(len)-1;
for(i;i>=0;i--){
for(int j=0;j<len;j+=(2<<i)){
for(int k=0;k<1<<i;k++){
ll l=a[j+k],r=a[j+(1<<i)+k];
a[j+k]=(l+r)*inv2%mod;
a[j+(1<<i)+k]=(l-r+mod)*inv2%mod;
}
}
}
}
int n;
ll a[1<<18];
ll b[1<<18];
ll c[1<<18];
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%lld",&a[i]);
for(int i=0;i<n;i++)scanf("%lld",&c[i]);
fwt(a,n);
fwt(c,n);
for(int i=0;i<n;i++)b[i]=c[i]*power(a[i],mod-2)%mod;
rfwt(b,n);
for(int i=0;i<n;i++)printf("%lld\n",b[i]);
}
C
找规律dp,强行莫队
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll power(ll n,ll p){
ll ans=1;
ll base=n;
while(p){
if(p&1)ans=ans*base%mod;
p>>=1;
base=base*base%mod;
}
return ans;
}
ll fac[400005];
ll inv[400005];
ll C(ll x,ll y){
ll ans=fac[x];
ans=ans*inv[y]%mod;
ans=ans*inv[x-y]%mod;
return ans;
}
void debug(){
ll x,y;
while(cin>>x>>y){
cout<<C(x,y)<<endl;
}
}
ll n,m;
struct node{
ll x,y,id;
}rec[400005];
ll tot;
bool cmp(node a,node b){
if(a.x/400==b.x/400){
if((a.x/400)&1)return a.y<b.y;
return a.y>b.y;
}
return a.x<b.x;
}
ll res[400005];
ll rx[400005],ry[400005];
ll dir[400005];
bool flag=true;
void addquery(){
scanf("%lld",&n);
ll x=0,y=0;
ll op;
m=0;
while(~scanf("%lld",&op)){
m++;
// cout<<op<<endl;
rx[m]=x,ry[m]=y;
rec[++tot]=(node){2*n-x-y-1,n-y-1,2*m-1};
// cout<<rec[tot].x<<' '<<rec[tot].y<<endl;
rec[++tot]=(node){2*n-x-y-1,n-x-1,2*m};
// cout<<rec[tot].x<<' '<<rec[tot].y<<endl;
if(op==0){y++;dir[m]=0;}
else {x++;dir[m]=1;}
}
if(x>y)flag=true;
else flag=false;
}
void solvequery(){
sort(rec+1,rec+1+tot,cmp);
ll tx=1,ty=0;
ll tmp=1;
for(ll i=1;i<=tot;i++){
while(tx<rec[i].x){
tmp=(2*tmp-C(tx,ty)+mod)%mod;
tx++;
}
while(ty>rec[i].y){
tmp=(tmp-C(tx,ty)+mod)%mod;
ty--;
}
while(tx>rec[i].x){
tmp=(tmp+C(tx-1,ty))*inv[2]%mod;
tx--;
}
while(ty<rec[i].y){
tmp=(tmp+C(tx,ty+1))%mod;
ty++;
}
res[rec[i].id]=tmp;
}
}
ll path[400005];
ll totp=0;
void print(){
for(ll i=1;i<=m;i++){
//cout<<res[2*i-1]<<endl;
//cout<<res[2*i]<<endl;
ll ans=power(2,rx[i]+ry[i]);
ll mul=(res[2*i-1]-res[2*i]+mod)%mod;
ans=ans*mul%mod;
path[++totp]=ans;
//printf("%lld\n",ans);
}
ll ed=power(2,2*n-1);
if(flag)path[++totp]=ed;
else path[++totp]=(mod-ed)%mod;
for(ll i=2;i<=totp;i++){
if(dir[i-1]==0){
printf("%lld\n",(path[i-1]-path[i]+mod)%mod);
}else {
printf("%lld\n",(path[i]-path[i-1]+mod)%mod);
}
}
}
int main(){
fac[0]=inv[0]=1;
for(ll i=1;i<=200001;i++){
fac[i]=fac[i-1]*i%mod;
inv[i]=power(fac[i],mod-2);
}
// debug();
addquery();
solvequery();
print();
}
E
dp
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int N=1010;
ll inv100;
ll qpow(ll x, ll y){
ll ans=1;
while(y){
if(y&1) ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return ans;
}
ll inv(ll x){
return qpow(x,mod-2);
}
int n,m;
int p[N];
ll dp[N][2];
int main(){
inv100=inv(100);
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++){
scanf("%d",&p[i]);
dp[i][0]=(dp[i-1][0]+dp[i-1][1])*(100-p[i])%mod*inv100%mod;
dp[i][1]=0;
ll tmp,xs=p[i]*inv100%mod;
for(int j=i-1; j>=0; j--){
tmp=(dp[j][0]+qpow(i-j,m)*(100-p[j])%mod*inv100%mod)*xs%mod;
dp[i][1]+=tmp;
xs=xs*p[j]%mod*inv100%mod;
}
//cout<<i<<": "<<dp[i][0]<<" "<<dp[i][1]<<endl;
dp[i][1]%=mod;
}
printf("%lld\n",(dp[n][0]+dp[n][1])%mod);
return 0;
}
F
AC自动机反过来搞一搞
//AC自动机
//查询模式串出现次数
#include <bits/stdc++.h>
using namespace std;
queue<int>que;
int ans[100003];
vector<int>g[100003];
struct Trie{
int ch[100003][26];
int fail[100003];
int end[100003];
int sz;
int newnode(){
for(int i=0;i<26;i++)ch[sz][i]=-1;
end[sz]=0;
return sz++;
}
void init(){
memset(end,0,sizeof(end));
sz=0;
newnode();
}
int idx(char c){
return c-'a';
}
void insert(char s[]){
int len=strlen(s);
int u=0;
for(int i=0;i<len;i++){
int c=idx(s[i]);
if(ch[u][c]==-1){
ch[u][c]=newnode();
}
u=ch[u][c];
}
end[u]=1;
//que.push(u);
//ans[u]=1;
}
void build(){
queue<int>q;
fail[0]=0;
for(int i=0;i<26;i++){
if(ch[0][i]==-1)ch[0][i]=0;
else {
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<26;i++){
if(ch[u][i]==-1){
ch[u][i]=ch[fail[u]][i];
}
else {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
for(int i=0;i<sz;i++){
if(end[fail[i]])end[i]=1;
//cout<<i<<' '<<fail[i]<<' '<<end[i]<<endl;
if(end[i]){
que.push(i);
ans[i]=1;
}
}
}
void buildr(){
for(int i=0;i<sz;i++){
for(int j=0;j<26;j++){
g[ch[i][j]].push_back(i);
}
}
}
};
Trie T;
char s[100003];
int rec[100003];
int len=0;
int main(){
while(!que.empty())que.pop();
T.init();
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
T.insert(s);
}
T.build();
T.buildr();
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(ans[v])continue;
ans[v]=ans[u]+1;
que.push(v);
}
}
scanf("%s",s);
printf("%d\n",ans[rec[len]]-1);
for(int i=0;s[i];i++){
if(s[i]=='-'){
if(len){
len--;
}
printf("%d\n",ans[rec[len]]-1);
}
else {
int c=s[i]-'a';
int v=T.ch[rec[len]][c];
rec[++len]=v;
printf("%d\n",ans[rec[len]]-1);
}
//cout<<rec[len]<<endl;
}
}
H
分块暴力
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll power(ll n,ll p){
ll ans=1;
ll base=n;
while(p){
if(p&1)ans=ans*base%mod;
base=base*base%mod;
p>>=1;
}
return ans;
}
ll fac[200003];
ll inv[200003];
ll C(ll n,ll m){
// cout<<n<<' '<<m<<endl;
ll ret=fac[n];
ret=ret*inv[m]%mod;
ret=ret*inv[n-m]%mod;
return ret;
}
int n,m,k;
ll a[41][100003];
void debug(){
ll x,y;
while(cin>>x>>y){
cout<<C(x,y)<<endl;
}
}
int x[2003];
int y[2003];
int top=0;
int main(){
fac[0]=inv[0]=1;
for(int i=1;i<=200000;i++){
fac[i]=fac[i-1]*i%mod;
inv[i]=power(fac[i],mod-2);
}
//debug();
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++){
int op;
scanf("%d",&op);
if(op==1){
int p;
scanf("%d",&p);
ll ans=a[k][p];
for(int j=1;j<=top;j++){
if(x[j]>p)continue;
ans+=C(k-1+p-x[j],k-1)*y[j];
ans%=mod;
}
printf("%d\n",ans);
}
else if(op==0){
++top;
scanf("%d%d",&x[top],&y[top]);
}
if(i%2000==0){
while(top){
a[0][x[top]]+=y[top];
if(a[0][x[top]]>=mod)a[0][x[top]]-=mod;
top--;
}
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++){
a[i][j]=a[i-1][j]+a[i][j-1];
if(a[i][j]>=mod)a[i][j]-=mod;
}
}
}
}
}