l d x ldx ldx 级别的送分题
代码:
#include
#define ri register int
#define pb push_back
using namespace std;
const int rlen=1<<18|1;
typedef long long ll;
typedef long double ld;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int mod=1e9+7;
inline int add(int a,int b){return (a+=b)<mod?a:a-mod;}
inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline void Add(int&a,int b){(a+=b)<mod?a:(a-=mod);}
inline void Dec(int&a,int b){(a-=b)<0?(a+=mod):a;}
inline void Mul(int&a,int b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,Mul(a,a))if(p&1)Mul(ret,a);return ret;}
const ld eps=1e-6;
inline int sgn(ld x){return (x>eps)-(x<eps);}
struct Node{
ld vl;
int a,b;
friend inline bool operator<(Node a,Node b){
int t=sgn(a.vl-b.vl);
return t?t<0:a.b<b.b;
}
};
priority_queue<Node>q;
int n,k;
vector<int>tg,fac,ifac;
vector<ld>ft;
inline void init(){
tg.resize(n+1),fac.resize(n+1),ifac.resize(n+1),ft.resize(n+1);
fac[0]=fac[1]=ifac[0]=ifac[1]=1;
for(ri i=2;i<=n;++i)fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[mod-mod/i*i],mod-mod/i);
for(ri i=2;i<=n;++i)Mul(ifac[i],ifac[i-1]);
for(ri i=1;i<=n;++i)ft[i]=ft[i-1]+log2(i);
}
inline ld ldxC(int n,int m){return ft[n]-ft[m]-ft[n-m];}
inline int C(int n,int m){return n<m?0:mul(fac[n],mul(ifac[m],ifac[n-m]));}
int main(){
#ifdef ldxcaicai
freopen("lx.in","r",stdin);
#endif
cin>>n>>k;
init();
for(ri i=0;i<=n;++i){
tg[i]=i>>1;
q.push((Node){ldxC(i,i>>1),i,1+(i&1)});
}
int res=0;
while(k){
Node x=q.top();
q.pop();
for(ri i=min(x.b,k);i;--i)Add(res,C(x.a,tg[x.a]));
k-=min(x.b,k);
--tg[x.a];
if(tg[x.a]>=0)q.push((Node){ldxC(x.a,tg[x.a]),x.a,2});
}
cout<<res;
return 0;
}
l d x ldx ldx 难度的回滚莫队+可回退化链表
代码:
#include
#define ri register int
#define pb push_back
using namespace std;
const int rlen=1<<18|1;
typedef long long ll;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
inline int Read(char*s){
int tp=0;
char ch=gc();
while(!isalpha(ch))ch=gc();
while(isalpha(ch))s[++tp]=ch,ch=gc();
return tp;
}
const int N=1e5+5,M=3e5+5;
char s[M];
ll ans[N],ss,sum[M];
int pre[M],suf[M],cnt[M],tim[M];
int n,A,B,C,m,vl[M],g[M],L,Vl[N],ban[M],dep[M];
int son[M][26],pos[M],Len[N],treetot=1,tot=0;
inline void insert(char*s,int n,int vll){
int p=1;
for(ri x,i=1;i<=n;++i){
x=s[i]-'a';
if(!son[p][x])son[p][x]=++treetot,dep[son[p][x]]=dep[p]+1;
p=son[p][x];
pos[++tot]=p;
vl[tot]=vll;
sum[p]+=vll;
++tim[p];
}
}
int blo;
inline int findblo(int x){return (x-1)/blo+1;}
struct Qry{int l,r,id;friend inline bool operator<(Qry a,Qry b){return a.r>b.r;}};
vector<Qry>qry[1005];
inline ll dis(int a,int b){return (ll)(b-a-1)*(b-a)/2;}
inline void add(int p){
bool ff=1;
int t;
if(tim[pos[p]]&&sum[pos[p]]>=ban[dep[pos[p]]])ff=0;
sum[pos[p]]+=vl[p];
++tim[pos[p]];
if(sum[pos[p]]<ban[dep[pos[p]]])ff=0;
if(ff){
t=g[dep[pos[p]]];
++cnt[t];
if(cnt[t]==1){
ss=ss+dis(pre[t],t)+dis(t,suf[t])-dis(pre[t],suf[t]);
suf[pre[t]]=t,pre[suf[t]]=t;
}
}
}
inline void dec(int p){
bool ff=1;
int t;
if(sum[pos[p]]<ban[dep[pos[p]]])ff=0;
sum[pos[p]]-=vl[p];
--tim[pos[p]];
if(tim[pos[p]]&&sum[pos[p]]>=ban[dep[pos[p]]])ff=0;
if(ff){
t=g[dep[pos[p]]];
--cnt[t];
if(cnt[t]==0){
ss=ss-dis(pre[t],t)-dis(t,suf[t])+dis(pre[t],suf[t]);
suf[pre[t]]=suf[t],pre[suf[t]]=pre[t];
}
}
}
int ori=1;
inline void solvebig(int id){
if(!qry[id].size())return;
sort(qry[id].begin(),qry[id].end());
int R=tot,L=(id-1)*blo+1;
while(ori!=L)dec(ori++);
for(ri i=0,up=qry[id].size();i<up;++i){
while(R!=qry[id][i].r)dec(R--);
while(L!=qry[id][i].l)dec(L++);
ans[qry[id][i].id]=ss;
while(L!=ori)add(--L);
}
while(R!=tot)add(++R);
}
inline ll gcd(ll a,ll b){ll t;while(b)t=a,a=b,b=t-t/a*a;return a;}
vector<int>tp;
int main(){
#ifdef ldxcaicai
freopen("lx.in","r",stdin);
freopen("lx.out","w",stdout);
#endif
n=read(),A=read(),B=read(),C=read(),L=0;
for(ri i=1;i<=n;++i)Vl[i]=read();
for(ri len,i=1;i<=n;++i){
len=Read(s);
Len[i]=len+Len[i-1];
L=max(L,len);
insert(s,len,Vl[i]);
}
for(ri i=1;i<=L;++i)g[i]=read(),ban[i]=C>=(ll)A*i?(C-A*i+B-1)/B:0;
blo=min(tot,300);
for(ri i=2;i<=treetot;++i)if(sum[i]>=ban[dep[i]])tp.pb(g[dep[i]]);
sort(tp.begin(),tp.end());
for(ri i=0;i<tp.size();++i)++cnt[tp[i]];
tp.erase(unique(tp.begin(),tp.end()),tp.end());
if(tp.size()){
pre[tp[0]]=0,suf[tp.back()]=L+1;
suf[0]=tp[0],pre[L+1]=tp.back();
for(ri i=0;i<tp.size();++i){
if(i)pre[tp[i]]=tp[i-1];
if(i+1!=tp.size())suf[tp[i]]=tp[i+1];
}
}
else pre[L+1]=0,suf[0]=L+1;
ss=0;
for(ri i=0;i!=L+1;i=suf[i])ss+=dis(i,suf[i]);
m=read();
for(ri i=1,l,r;i<=m;++i){
l=Len[read()-1]+1,r=Len[read()];
qry[findblo(l)].pb((Qry){l,r,i});
}
for(ri i=1,up=findblo(tot);i<=up;++i)solvebig(i);
ll all=(ll)L*(L+1)/2,g;
for(ri i=1;i<=m;++i){
g=gcd(all,ans[i]);
cout<<(all-ans[i])/g<<'/'<<all/g<<'\n';
}
return 0;
}
z x y zxy zxy 难度的算计建图+ l d x ldx ldx 难度的 01 t r i e 01trie 01trie 合并优化 S G SG SG 图上 d p dp dp
由于前者是 z x y zxy zxy 难度于是放弃了,后者是这个题
COT3的代码:
#include
#define ri register int
#define pb push_back
using namespace std;
const int rlen=1<<18|1;
char buf[rlen],*ib=buf,*ob=buf;
#define gc() (((ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin)),ib==ob)?-1:*ib++)
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=1e5+5,Dep=15,M=3e6+5;
int n,col[N],rt[N],f[N];
vector<int>e[N],ans;
namespace trie{
#define lc (son[p][0])
#define rc (son[p][1])
int son[M][2],tg[M],tot=0;
bool ok[M];
inline void pushnow(int p,int v,int dep){
if(v>>dep&1)swap(lc,rc);
tg[p]^=v;
}
inline void pushdown(int p,int dep){if(dep&&tg[p])pushnow(lc,tg[p],dep-1),pushnow(rc,tg[p],dep-1);tg[p]=0;}
inline void update(int&p,int v,int dep=Dep){
p=++tot;
if(dep==-1){ok[p]=1;return;}
update(son[p][v>>dep&1],v,dep-1);
}
inline int merge(int a,int b,int dep=Dep){
if(!a||!b)return a|b;
if(dep==-1)return ok[a]|=ok[b],a;
pushdown(a,dep),pushdown(b,dep);
son[a][0]=merge(son[a][0],son[b][0],dep-1);
son[a][1]=merge(son[a][1],son[b][1],dep-1);
return ok[a]=ok[son[a][0]]&ok[son[a][1]],a;
}
inline int mex(int p,int dep=Dep){
if(!p||dep==-1)return 0;
pushdown(p,dep);
if(!ok[lc])return mex(lc,dep-1);
return (1<<dep)|mex(rc,dep-1);
}
#undef lc
#undef rc
}
void dfs1(int p,int ft){
int s=0;
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==ft)continue;
dfs1(v,p);
s^=f[v];
}
if(!col[p])trie::update(rt[p],s);
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==ft)continue;
trie::pushnow(rt[v],s^f[v],Dep);
rt[p]=trie::merge(rt[p],rt[v]);
}
f[p]=trie::mex(rt[p]);
}
void dfs2(int p,int ft,int pre){
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==ft)continue;
pre^=f[v];
}
if(!col[p]&&!pre)ans.pb(p);
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==ft)continue;
dfs2(v,p,pre^f[v]);
}
}
int main(){
#ifdef ldxcaicai
freopen("lx.in","r",stdin);
#endif
n=read();
for(ri i=1;i<=n;++i)col[i]=read();
for(ri i=1,u,v;i<n;++i){
u=read(),v=read();
e[u].pb(v);
e[v].pb(u);
}
dfs1(1,0);
dfs2(1,0,0);
if(!ans.size())puts("-1");
else{
sort(ans.begin(),ans.end());
for(ri i=0;i<ans.size();++i)cout<<ans[i]<<' ';
}
return 0;
}