1.12
fAKe restore basic skills training
(I'm from the future: Anyway, the topic than 1.15 to harder)
T1 Mr. toluene roll list
Balanced tree board questions, to maintain two elements
Balanced tree board link (comment in great detail)
Paste codes (Splay):
#include <bits/stdc++.h>
#define N (1000000+5)
#define DEBUG puts("!!!");
using namespace std;
typedef unsigned int ui;
ui randNum(ui &seed, ui last,const ui m){
seed=seed*17+last;
return seed%m+1;
}
ui m,sd,lst=7;
int t,n;
int rt,tot,fa[N],cnt[N],ch[N][2],vala[N],valb[N],siz[N];
int nowa[N],nowb[N];
inline void maintain(int x){
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
}
inline bool get(int x){
return x==ch[fa[x]][1];
}
inline void clear(int x){
ch[x][0]=ch[x][1]=fa[x]=cnt[x]=vala[x]=valb[x]=siz[x]=0;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],k=get(x);
ch[y][k]=ch[x][k^1];
fa[ch[x][k^1]]=y;
ch[x][k^1]=y;
fa[y]=x;
fa[x]=z;
if(z) ch[z][y==ch[z][1]]=x;
maintain(y),maintain(x);
}
inline void splay(int x,int g=0){
while(fa[x]!=g){
int f=fa[x],ff=fa[f];
if(ff!=g) get(x)==get(f)?rotate(f):rotate(x);
rotate(x);
}
if(!g) rt=x;
}
inline void insert(int a,int b){
if(!rt){
vala[++tot]=a,valb[tot]=b;
rt=tot,cnt[tot]++;
maintain(rt);
return;
}
int cnr=rt,f=0;
while(1){
if(vala[cnr]==a&&valb[cnr]==b){
cnt[cnr]++;
maintain(cnr);
splay(cnr);
break;
}
f=cnr;
if(a<vala[cnr]||(a==vala[cnr]&&b>valb[cnr])) cnr=ch[cnr][1];
else cnr=ch[cnr][0];
if(!cnr){
vala[++tot]=a,valb[tot]=b;
cnt[tot]++;
fa[tot]=f,ch[f][a<vala[f]||(a==vala[f]&&b>valb[f])]=tot;
maintain(f),maintain(tot);
splay(tot);
break;
}
}
}
inline int rk(int a,int b){
int res=0,cnr=rt;
while(1){
if(a>vala[cnr]||(a==vala[cnr]&&b<valb[cnr])) cnr=ch[cnr][0];
else{
res+=siz[ch[cnr][0]];
if(a==vala[cnr]&&b==valb[cnr]){
splay(cnr);
return res+1;
}
res+=cnt[cnr];
cnr=ch[cnr][1];
}
}
}
inline int pre(){
int cnr=ch[rt][0];
while(ch[cnr][1]) cnr=ch[cnr][1];
return cnr;
}
inline void del(int a,int b){
rk(a,b);
if(cnt[rt]>1){
cnt[rt]--,maintain(rt);
return;
}
if(!ch[rt][0]&&!ch[rt][1]){
clear(rt),rt=0;
return;
}
if(!ch[rt][0]){
int cnr=rt;
rt=ch[cnr][1];
fa[rt]=0;
clear(cnr);
return;
}
if(!ch[rt][1]){
int cnr=rt;
rt=ch[cnr][0];
fa[rt]=0;
clear(cnr);
return;
}
int x=pre(),cnr=rt;
splay(x);
fa[ch[cnr][1]]=x;
ch[x][1]=ch[cnr][1];
clear(cnr);
maintain(rt);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&m,&n,&sd);
memset(nowa,0,sizeof(nowa));//过于 chou lou
memset(nowb,0,sizeof(nowb));
memset(fa,0,sizeof(fa));
memset(ch,0,sizeof(ch));
memset(cnt,0,sizeof(cnt));
memset(vala,0,sizeof(vala));
memset(valb,0,sizeof(valb));
memset(siz,0,sizeof(siz));
rt=0,tot=0;
while(n--){
ui ria=randNum(sd,lst,m);
ui rib=randNum(sd,lst,m);
if(nowa[ria]) del(nowa[ria],nowb[ria]);
nowa[ria]++,nowb[ria]+=rib;
insert(nowa[ria],nowb[ria]);
lst=rk(nowa[ria],nowb[ria])-1;
printf("%d\n",lst);
}
}
return 0;
}
T2 counting arrangement
emmm I did not write too dishes
Mainly derive the number of combinations, details of problem solution Luo Valley Look, I have time to fix. . .
And more than the number of T3
Divisible block template title
\ (Ans = \ sigma_ {i = 1} ^ {n} {k% i} \)
又∵ \(a%b = a - b \times \lfloor {\frac{a}{b}} \rfloor\)
∴ \(ans = \sigma_{i=1}^{n}{k-i \times \lfloor {\frac{k}{i}} \rfloor} = n \times k - \sigma_{i=1}^{n}{i \times \lfloor {\frac{k}{i}} \rfloor}\)
Then divisible block operation \ (\ lfloor {\ frac { k} {i}} \ rfloor \)
Paste code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n,k,ans;
int main(){
scanf("%lld%lld",&n,&k);
ans=n*k;
for(LL l=1,r=0;l<=n;l=r+1){
LL t=k/l;
if(t){
r=min(k/t,n);
}
else r=n;
ans-=t*(r-l+1)*(l+r)>>1;
}
printf("%lld",ans);
return 0;
}
1.15
~ Really restore basic skills training
Today's emergent topics, the questions are all board
T1 bird snacks
(SBT) Shortest board problem, the queue using Dijkstra, its height limit point not to join
Sure enough, is to restore basic skills training, engage in two months of culture, I do not even remember Dijkstra wrote (I guess I was the first to open Djkstra inside the heap into large root heap)
Paste code:
#include <bits/stdc++.h>
#define N (200000+5)
#define int long long
using namespace std;
typedef pair<int,int> paii;
int n,m,s,t,g,x;
int h[N],lim[N],dis[N],vis[N];
vector<intnanyixie> edge[N],w[N];
void add(int u,int v,int wei){
edge[u].push_back(v);
w[u].push_back(wei);
edge[v].push_back(u);
w[v].push_back(wei);
}
void dijkstra(){
priority_queue <paii,vector<paii>,greater<paii> > q;//呜呜呜~~~
dis[s]=0;
int u=s;
q.push(make_pair(0,s));
while(!q.empty()){
u=q.top().second;q.pop();
vis[u]=1;
for(int i=0;i<edge[u].size();i++){
int now=edge[u][i];
if(dis[now]>dis[u]+w[u][i]){
dis[now]=dis[u]+w[u][i];
if(!vis[now]&&(dis[now]*x+h[now]<=lim[now])){//高度超限的不加入堆
q.push(make_pair(dis[now],now));
}
}
}
}
}
signed main(){
freopen("oyatsu.in","r",stdin);//留着防抄
freopen("oyatsu.out","w",stdout);
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&s,&t,&g,&x);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&h[i],&lim[i]);
}
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=m;i++){
int u,v,wei;
scanf("%lld%lld%lld",&u,&v,&wei);
add(u,v,wei);
}
dijkstra();
if(dis[t]<=g) printf("%lld",dis[t]);
else puts("wtnap wa kotori no oyatsu desu!");
return 0;
}
T2 leader of the magic
Block board problem, only yesterday I wrote
On the code, do not explain, and explain the point to look at the link above
#include <bits/stdc++.h>
#define N (1000000+5)
using namespace std;
int n,q,k,bl,a[N],pos[N],lazy[N],L[N],R[N];
vector <int> v[N];
void Update(int x){
v[x].clear();
for(int i=L[x];i<=R[x];i++){
v[x].push_back(a[i]);
}
sort(v[x].begin(),v[x].end());
}
void add(int l,int r,int c){
for(int i=l;i<=min(R[pos[l]],r);i++){
a[i]+=c;
}
Update(pos[l]);
if(pos[l]!=pos[r]){
for(int i=L[pos[r]];i<=r;i++){
a[i]+=c;
}
Update(pos[r]);
}
for(int i=pos[l]+1;i<pos[r];i++) lazy[i]+=c;
}
int query(int l,int r,int c){
int x=0;
for(int i=l;i<=min(R[pos[l]],r);i++){
int sum=lazy[pos[l]]+a[i];
if(sum<c) x++;
}
if(pos[l]!=pos[r]){
for(int i=L[pos[r]];i<=r;i++){
int sum=lazy[pos[l]]+a[i];
if(sum<c) x++;
}
}
for(int i=pos[l]+1;i<pos[r];i++){
int t=c-lazy[i];
x+=lower_bound(v[i].begin(),v[i].end(),t)-v[i].begin();
}
return x;
}
int main(){
freopen("magic.in","r",stdin);//防抄
freopen("magic.out","w",stdout);
scanf("%d%d",&n,&q);
k=sqrt(n),bl=n/k+(n%k!=0);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
pos[i]=(i-1)/k+1;
v[pos[i]].push_back(a[i]);
}
for(int i=1;i<=bl;i++){
L[i]=(i-1)*k+1,R[i]=i*k;
sort(v[i].begin(),v[i].end());
}
R[bl]=n;
for(int i=1;i<=q;i++){
char opt;
int l,r,c;
scanf("%s",&opt);
scanf("%d%d%d",&l,&r,&c);
if(opt=='M') add(l,r,c);
else if(opt=='A') printf("%d\n",r-l+1-query(l,r,c));
}
return 0;
}
T3 sum
LCA title board, pre-k to the power of every number, and add a prefix to ensure \ (O (1) \) Inquiry
The other is not difficult
估计我又是第一个把\(log_2 n\)写成\(log n\)的数学“带师”
果然我的基本功还不够扎实,不过看起来比可爱的Enterprise小姐姐好,反正都是爆零嘛~
贴一个代码,不解释了
#include <bits/stdc++.h>
#define N (300000+50)
using namespace std;
typedef long long LL;
const int mod=998244353;
int n,m,rt=1;
LL f[N][55],sum[55][N],ans;
int depth[N],fa[N][30],lgn;
vector<int> edge[N];
void add(int u,int v){
edge[u].push_back(v);
edge[v].push_back(u);
}
void dfs(int u,int father){
for(int i=0;i<edge[u].size();i++){
int now=edge[u][i];
if(now==father) continue;
else depth[now]=depth[u]+1,fa[now][0]=u;
dfs(now,u);
}
}
void getfather(){
for(int j=1;j<=lgn;j++){
for(int i=1;i<=n;i++){
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
}
int LCA(int u,int v){
if(depth[u]<depth[v]) swap(u,v);
int dist=depth[u]-depth[v];
for(int j=0;j<=lgn;j++){
if((1<<j)&dist) u=fa[u][j];
}
if(u==v) return u;
for(int j=lgn;j>=0;j--){
if(fa[u][j]!=fa[v][j]){
u=fa[u][j];
v=fa[v][j];
}
}
return fa[u][0];
}
void init(){
for(int i=1;i<=300005;i++){
for(int j=0;j<=50;j++){
if(j==0) f[i][j]=1;
else f[i][j]=f[i][j-1]%mod*i%mod;
}
}
for(int i=1;i<=50;i++){
for(int j=0;j<=300005;j++){
sum[i][j]=(sum[i][j-1]+f[j][i])%mod;
}
}
}
int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
init();
scanf("%d",&n);
lgn=log2(n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
dfs(rt,0);
getfather();
scanf("%d",&m);
for(int i=1;i<=m;i++){
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
int lca=LCA(u,v);
int du=depth[u],dv=depth[v],dl=depth[lca];
if(lca==u){
printf("%lld\n",(sum[k][dv]-sum[k][du-1]+mod)%mod);
}
else if(lca==v){
printf("%lld\n",(sum[k][du]-sum[k][dv-1]+mod)%mod);
}
else printf("%lld\n",((sum[k][du]-sum[k][dl-1]+mod)%mod+(sum[k][dv]-sum[k][dl-1]+mod)%mod-f[dl][k]+mod)%mod);
}
return 0;
}
总结
看来还要多多训练才行啊