NOIP模拟 八十三

csp后第一次模拟,好像以后都和外校联考了。

60+90+25+30

菜。。。。。。。。。。。。。。。。。。

T1T2被大力卡常,T3T4只会暴力。。

冲刺NOIP2021模拟16 树上的数

一眼线段树傻逼题,然后看到5000000,貌似可以带个 log,于是就没多想。

其实扫一遍也挺显然的。。

垃圾oj跑个 n 的5000000跑了一秒六,怕不是上世纪五十年代的剩余产品?

#include<bits/stdc++.h>
#define N 5000050
#define mod 19760817
using namespace std;
int a,b,n,m,dfn[N],siz[N],sum[N<<2],tag[N<<2],head[N],tot,cnt,id[N],ans,tmp,jie;
long long q,f[N];
bool vis[N];
struct jj{int to,nxt;}bian[N];
inline void add(int u,int v)
{   bian[++tot].to=v;
    bian[tot].nxt=head[u];
    head[u]=tot;
}
inline void work(int x)
{   if(vis[x])return;vis[x]=1;++tmp;
    for(int i=head[x];i;i=bian[i].nxt){work(bian[i].to);}
}
signed main()
{   freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    scanf("%d%d",&n,&m);scanf("%d%d",&a,&b);f[2]=1;
    for(int i=3;i<=n;++i)f[i]=((1ll*f[i-1]*a+b)^mod)%(i-1)+1;
    for(int i=2;i<=n;++i)add(f[i],i);
    long long x,y;
    scanf("%lld%lld%lld",&q,&x,&y);
    work(q);ans=n-tmp;jie=n-tmp;
    for(int i=2;i<=m;++i)
    {   q=(((q*x+y)^mod)^(i<<1))%(n-1)+2;
        tmp=0;work(q);jie-=tmp;ans^=jie;
    }
    printf("%d\n",ans);
}

T2冲刺NOIP2021模拟16 时代的眼泪

大概就是个数据结构,然后写了线段树合并,1e6跑两秒跑不出来。。

换用树状数组容斥求子树内的个数就能过了。

#include<bits/stdc++.h>
#define N 1000050
using namespace std;
int w[N],n,head[N],cnt,tot,q,san[N],root[N],id[N],c[N],zhui[N];
long long ans[N];
struct jj{int to,nxt;}bian[N<<1];
inline void add(int u,int v)
{   bian[++tot].to=v;
    bian[tot].nxt=head[u];
    head[u]=tot;
}
inline int read()
{   int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
inline void write(long long x,char ch='\n')
{   static int sta[35]; int top=0;
	if(x<0) putchar('-'),x=-x;
	do{sta[++top]=x%10,x/=10;}while(x);
	while(top) putchar(sta[top--]+48); putchar(ch);
}
inline void add(int x){for(int i=x;i<=n;i+=i&-i)++c[i];}
inline int query(int x){int res=0;for(int i=x;i>0;i-=i&-i)res+=c[i];return res;}
inline void dfs(int x,int fa)
{   int tmp1=query(id[x]-1),tmp2=query(id[fa]-1);add(id[x]);
    for(int i=head[x];i;i=bian[i].nxt)
    {   int v=bian[i].to;
        if(v==fa)continue;dfs(v,x);
    }
    if(id[x]!=1)
    {   int tmp=query(id[x]-1)-tmp1;
        ans[1]+=tmp;if(x!=1)ans[x]-=tmp;
    }
    if(id[fa]!=1 and x!=1)ans[x]-=(query(id[fa]-1)-tmp2);
}
inline void get_ans(int x,int fa)
{   if(x!=1){ans[x]+=zhui[id[x]-1]+ans[fa];}
    for(int i=head[x];i;i=bian[i].nxt)
    {   int v=bian[i].to;
        if(v==fa)continue;
        get_ans(v,x);
    }
}
signed main()
{   freopen("tears.in","r",stdin);
    freopen("tears.out","w",stdout);
    n=read();q=read();
    for(int i=1;i<=n;++i)w[i]=read(),san[++cnt]=w[i];
    for(int i=1;i<n;++i)
    {   int a,b;
        a=read();b=read();
        add(a,b);add(b,a);
    }
    sort(san+1,san+1+cnt);cnt=unique(san+1,san+1+cnt)-san-1; 
    for(int i=1;i<=n;++i)(id[i]=lower_bound(san+1,san+1+cnt,w[i])-san),++zhui[id[i]];
    for(int i=1;i<=n;++i)zhui[i]+=zhui[i-1];
    tot=0;dfs(1,0);
    for(int i=1;i<=q;++i){int x;x=read();write(ans[x]);}
}

T3 冲刺NOIP2021模拟16 传统艺能

线段树维护矩阵。

矩阵状态设计成谁开头,往后再预借一个谁的种类数。

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define N 400001
using namespace std;
int n,q;char a[N],c;
struct matrix
{   int c[4][4];
    friend matrix operator *(matrix a,matrix b)
    {   matrix c;memset(c.c,0,sizeof(c.c));
        for(int i=0;i<=3;++i)
        for(int j=0;j<=3;++j)
        for(int k=0;k<=3;++k)
        c.c[i][j]=(c.c[i][j]+a.c[i][k]*b.c[k][j]%mod)%mod;
        return c;
    }
}tmp,tree[N<<2];
inline void pushup(int x){tree[x]=tree[x<<1]*tree[x<<1|1];}
inline void build(int x,int l,int r)
{   if(l==r)
    {   memset(tree[x].c,0,sizeof(tree[x].c));
        for(int i=0;i<=3;++i)tree[x].c[i][i]=1;
        for(int i=0;i<=3;++i)tree[x].c[a[l]-'A'+1][i]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    pushup(x);    
}
inline void ins(int x,int l,int r,int pos,int val)
{   if(l==r)
    {   memset(tree[x].c,0,sizeof(tree[x].c));
        for(int i=0;i<=3;++i)tree[x].c[i][i]=1;
        for(int i=0;i<=3;++i)tree[x].c[val][i]=1;
        return;
    }
    int mid=(l+r)>>1;
    if(mid<pos)ins(x<<1|1,mid+1,r,pos,val);
    else ins(x<<1,l,mid,pos,val);
    pushup(x);
}
inline matrix query(int x,int l,int r,int L,int R)
{   if(l>=L and r<=R)return tree[x];
    int mid=(l+r)>>1;
    if(mid>=R)return query(x<<1,l,mid,L,R);
    else if(mid<L)return query(x<<1|1,mid+1,r,L,R);
    else return query(x<<1,l,mid,L,R)*query(x<<1|1,mid+1,r,L,R);
}
signed main()
{   freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    scanf("%lld%lld",&n,&q);scanf("%s",a+1);
    build(1,1,n);
    for(int i=1;i<=q;++i)
    {   int opt,pos,l,r;
        scanf("%lld",&opt);
        if(opt==1)
        {   scanf("%lld %c",&pos,&c);
            ins(1,1,n,pos,c-'A'+1);
        }
        else
        {   scanf("%lld%lld",&l,&r);
            tmp=query(1,1,n,l,r);
            printf("%lld\n",(tmp.c[1][0]+tmp.c[2][0]+tmp.c[3][0])%mod);
        }
    }
}

T4冲刺NOIP2021模拟16 铺设道路

差分数组,然后削成0,最优就贪心选择。

#include <bits/stdc++.h>
#define N 300050
#define int long long
#define mod 1000000007
using namespace std;
int n, a[N], ans, ans1, ans2, b[N];
queue<int> q;
stack<int> sta;
signed main()
{
    freopen("road.in", "r", stdin);
    freopen("road.out", "w", stdout);
    scanf("%lld", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%lld", &a[i]);
    for (int i = 1; i <= n + 1; ++i)
        b[i] = a[i] - a[i - 1];
    for (int i = 1; i <= n + 1; ++i)
        ans = ans + max(b[i], 0ll);
    for (int i = 1; i <= n + 1; ++i)
    {
        if (b[i] > 0)
            q.push(i);
        else
        {
            while (b[i] < 0)
            {
                int id = q.front();
                if (abs(b[id]) <= abs(b[i]))
                {
                    b[i] += b[id];
                    ans1 = (ans1 + (i - id) * (i - id) % mod * b[id] % mod) % mod;
                    q.pop();
                }
                else
                {
                    b[id] += b[i];
                    ans1 = (ans1 + (i - id) * (i - id) % mod * (-b[i]) % mod) % mod;
                    b[i] = 0;
                }
            }
        }
    }
    for (int i = 1; i <= n + 1; ++i)
        b[i] = a[i] - a[i - 1];
    for (int i = 1; i <= n + 1; ++i)
    {
        if (b[i] > 0)
            sta.push(i);
        else
        {
            while (b[i] < 0)
            {
                int id = sta.top();
                if (abs(b[id]) <= abs(b[i]))
                {
                    b[i] += b[id];
                    ans2 = (ans2 + (i - id) * (i - id) % mod * b[id] % mod) % mod;
                    sta.pop();
                }
                else
                {
                    b[id] += b[i];
                    ans2 = (ans2 + (i - id) * (i - id) % mod * (-b[i]) % mod) % mod;
                    b[i] = 0;
                }
            }
        }
    }
    printf("%lld\n%lld\n%lld\n", ans, ans2, ans1);
}
posted @ 2021-10-26 18:50  -zxb-  阅读(53)  评论(0编辑  收藏  举报