[游记]暑假集训7-2022.8.21

A. One

一个线性的约瑟夫问题,考虑倒推

 

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define WR WinterRain
// #define int long long
using namespace std;
const int WR=10000010;
int n;
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+ch-48;
        ch=getchar();
    }
    return s*w;
}
signed main(){
    int t=read();
    while(t--){
        n=read();
        int pos=1,tot=1;
        for(int i=n-1;i;i--){
            tot++,pos++;
            pos=(pos-(i%tot)+tot)%tot;
            if(pos==0) pos+=tot;
        }
        printf("%d\n",n-pos+1);
    }
    return 0;
}
View Code

 

B. 砖块

一个小模拟,不能说困难但我赛时愣是没写

 

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=500010,INF=1099588621776;
int n,k,len,a,b,x,y,ans=0;
char opt[WR];
map<pair<int,int>,int>m;
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+ch-48;
        ch=getchar();
    }
    return s*w;
}
void workN(int &a,int &b,int &x,int &y){
    if(a==x){
        if(b==y) ++b,y+=k;
        else b=++y;
    }else ++b,++y;
    for(int i=a;i<=x;++i){
        for(int j=b;j<=y;++j){
            pair<int,int>pa=make_pair(i,j);
            if(m.find(pa)!=m.end()) m[pa]++;
            else m[pa]=1;
            ans=max(ans,m[pa]);
        }
    }
}
void workS(int &a,int &b,int &x,int &y){
    if(a==x){
        if(b==y) --y,b-=k;
        else y=--b;
    }else --b,--y;
    for(int i=a;i<=x;++i){
        for(int j=b;j<=y;++j){
            pair<int,int>pa=make_pair(i,j);
            if(m.find(pa)!=m.end()) m[pa]++;
            else m[pa]=1;
            ans=max(ans,m[pa]);
        }
    }
}
void workW(int &a,int &b,int &x,int &y){
    if(b==y){
        if(a==x) --x,a-=k;
        else x=--a;
    }else--a,--x;
    for(int i=a;i<=x;++i){
        for(int j=b;j<=y;++j){
            pair<int,int>pa=make_pair(i,j);
            if(m.find(pa)!=m.end()) m[pa]++;
            else m[pa]=1;
            ans=max(ans,m[pa]);
        }
    }
}
void workE(int &a,int &b,int &x,int &y){
    if(b==y){
        if(a==x) ++a,x+=k;
        else a=++x;
    }else ++x,++a;
    for(int i=a;i<=x;++i){
        for(int j=b;j<=y;++j){
            pair<int,int>pa=make_pair(i,j);
            if(m.find(pa)!=m.end()) m[pa]++;
            else m[pa]=1;
            ans=max(ans,m[pa]);
        }
    }
}
signed main(){
    n=read();
    while(n--){
        k=read();
        scanf("%s",opt+1);
        len=strlen(opt+1);
        a=b=x=y=0;
        m.clear();
        m[make_pair(0,0)]=ans=1;
        for(int i=1;i<=len;++i){
            if(opt[i]=='N') workN(a,b,x,y);
            else if(opt[i]=='S') workS(a,b,x,y);
            else if(opt[i]=='W') workW(a,b,x,y);
            else if(opt[i]=='E') workE(a,b,x,y);
        }
        if(a==x){
            for(int i=b;i<=y;++i) printf("%lld ",a);
            printf("\n");
            for(int i=b;i<=y;++i) printf("%lld ",i);
            printf("\n");
            printf("%lld\n",ans);
        }else{
            for(int i=a;i<=x;++i) printf("%lld ",i);
            printf("\n");
            for(int i=a;i<=x;++i) printf("%lld ",b);
            printf("\n");
            printf("%lld\n",ans);
        }
    }
    return 0;
}
View Code

 

C. 数字

看这里,毒瘤题目

 

D.甜圈

维护一棵线段树,

可以将每一个点的状态看作字符串进行哈希

这样可以做到 $\Theta(1)$ 查询是否合法

也有别的乱搞做法,比如直接硬维护也是可以的

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<algorithm>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=500010,INF=1099588621776;
struct SegmentTree{
    int l,r;
    int st,ed;
}tree[WR<<2];
int n,tot;
int ans;
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+ch-48;
        ch=getchar();
    }
    return s*w;
}
void update(int k,int l,int r){
    if(tree[k].st==0&&tree[k].l!=tree[k].r){
        tree[k].st=l,tree[k].ed=r;
    }else{
        if(tree[k].ed==l-1) tree[k].ed=r;
        else tree[k].st=-1;
    }
}
void pushdown(int k){
    update(k<<1,tree[k].st,tree[k].ed);
    update(k<<1|1,tree[k].st,tree[k].ed);
    tree[k].st=tree[k].ed=0;
}
void build(int k,int l,int r){
    tree[k].l=l,tree[k].r=r;
    if(l==r){
        tree[k].st=tree[k].ed=0;
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
void modify(int k,int l,int r,int val){
    if(tree[k].l>=l&&tree[k].r<=r){
        update(k,val,val);
        return;
    }
    if(tree[k].st) pushdown(k);
    int mid=(tree[k].l+tree[k].r)>>1;
    if(l<=mid) modify(k<<1,l,r,val);
    if(r>mid) modify(k<<1|1,l,r,val);
}
void dfs(int k){
    if(tree[k].l==tree[k].r){
        if(tree[k].st!=-1&&tree[k].ed==tot) ans++;
        return;
    }
    if(tree[k].st) pushdown(k);
    int mid=(tree[k].l+tree[k].r)>>1;
    dfs(k<<1);dfs(k<<1|1);
}
signed main(){
    n=read(),tot=read();
    int t=read();
    build(1,1,n);
    for(int i=1;i<=t;i++){
        int l=read(),r=read(),x=read();
        modify(1,l,r,x);
    }
    ans=0;
    dfs(1);
    printf("%lld\n",ans);
    return 0;
}
View Code
#include<bits/stdc++.h>
#define Re register ull
#define Sa Sakura
#define _ putchar(' ')
#define el putchar('\n')
#define maxn 200010
#define P 19260817
#define ull unsigned long long

using namespace std;

inline ull read(){
    ull x=0,f=0;char c=getchar();
    while(!isdigit(c)) f|=c=='-',c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return f?-x:x;
}

inline void ot(ull x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) ot(x/10);putchar(x%10|48);
}

struct node{
    ull pos,opt,d,t;
    #define pos(i) q[i].pos
    #define opt(i) q[i].opt
    #define d(i) q[i].d
    #define t(i) q[i].t
}q[maxn<<1];

inline bool cmp(const node A,const node B){
    return A.pos<B.pos;
}

ull n,m,k,ans;
ull Hs,base[maxn];
ull size[maxn<<2],hs[maxn<<2];

inline void pushup(ull p){
    size[p]=size[p<<1]+size[p<<1|1];
    hs[p]=hs[p<<1]*base[size[p<<1|1]]+hs[p<<1|1];
}

void update(ull p,ull l,ull r,ull pos,ull d){
    // if(p==1) ot(pos),_,ot(d),el;
    if(pos>r||pos<l) return;
    if(l==r){
        hs[p]=d;
        size[p]=hs[p]?1:0;
        return;
    }
    ull mid=l+r>>1;
    pos<=mid?update(p<<1,l,mid,pos,d):update(p<<1|1,mid+1,r,pos,d);
    pushup(p);
}

int main(){
    n=read(),k=read();
    for(Re i=1;i<=k;i++) Hs=Hs*P+i;
    // ot(Hs),el;
    base[0]=1;
    for(Re i=1;i<=k;i++) base[i]=base[i-1]*P;
    m=read();
    for(Re i=1;i<=m;i++){
        ull l=read(),r=read(),opt=read();
        pos(i*2-1)=l,opt(i*2-1)=opt,d(i*2-1)=1,t(i*2-1)=i;
        pos(i*2)=r+1,opt(i*2)=opt,d(i*2)=0,t(i*2)=i;
    }
    // for(Re i=1;i<=m*2;i++) ot(pos(i)),_,ot(opt(i)),_,ot(d(i)),_,ot(t(i)),el;el;
    sort(q+1,q+m*2+1,cmp);
    // for(Re i=1;i<=m*2;i++) ot(pos(i)),_,ot(opt(i)),_,ot(d(i)),_,ot(t(i)),el;
    ull p=1;
    for(Re i=1;i<=n;i++){
        while(p<=m*2&&pos(p)<=i){
            update(1,1,m,t(p),opt(p)*d(p));
            p++;
        }
        if(hs[1]==Hs) ans++;
    }
    ot(ans);
}
Sakura的哈希

 

posted @ 2022-08-21 16:52  冬天丶的雨  阅读(30)  评论(0编辑  收藏  举报
Live2D