zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试94]题解

    A.凉宫春日的忧郁

    高精硬上似乎跑不过,其实可以都取个$log$。那么只需要比较$y imes log ^x$和$sum limits _{i=1}^y log^i$就好了。

    #include<bits/stdc++.h>
    using namespace std;
    int T;
    double x,y;
    void work()
    {
        scanf("%lf%lf",&x,&y);
        double res1=y*log2(x);
        double res2=0;
        for(int i=1;i<=y;i++)
            res2+=log2(double(i));
        if(res1<=res2)puts("Yes");
        else puts("No");
    }
    
    int main()
    {
        freopen("yuuutsu.in","r",stdin);
        freopen("yuuutsu.out","w",stdout);
        scanf("%d",&T);
        while(T--)work();
        return 0;
    }
    

    B.漫无止境的八月

    显然目标区间合法的充要条件是:把位置按照$mod K$意义分组,每组的权值和应该相等。

    必要性:每次操作对于每一组的改变量都相同,所以最终的和也必然相等。

    充分性:……很显然吧。

    直接Hash表维护就好了,每次修改完判断是不是只有一种权值和即可。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ol
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int N=2e6+5;
    int n,K,Q,a[N],sum[N];
    struct Hashtable
    {
    #define mod 19260817
        int tot,head[19260820],nxt[N],to[N],val[N];
        int &operator [] (int v)
        {
            int x=v%mod;
            for(int i=head[x];i;i=nxt[i])
                if(to[i]==v)return val[i];
            to[++tot]=v;nxt[tot]=head[x];
            head[x]=tot;
            return val[tot]=0;
        }
    }s;
    int main()
    {
    #ifdef ol
        freopen("august.in","r",stdin);
        freopen("august.out","w",stdout);
    #endif
        n=read();K=read();Q=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        for(int i=1;i<=n;i++)
            sum[i%K]+=a[i];
        for(int i=0;i<K;i++)
            s[sum[i]]++;
        if(s[sum[0]]==K)puts("Yes");
        else puts("No");
        while(Q--)
        {
            int x=read(),val=read();
            a[x]+=val;
            s[sum[x%K]]--;
            sum[x%K]+=val;
            s[sum[x%K]]++;
            if(s[sum[0]]==K)puts("Yes");
            else puts("No");
        }
        return 0;
    }
    

    C.射手座之日

    构造一个新的点权$v'[x]=v[x]-v[fa[x]]$,那么区间权值就成了区间内所有元素的$lca$的权值和,从每个点的角度考虑就是它作为一些连续点的祖先的方案数再乘上点权。

    对于每个点建一棵线段树,维护左侧起最长连续段的端点,右侧起最长连续段的端点和方案数,线段树合并即可,维护过程类似于《山海经》。

    方案数就是可以取的连续区间数,即$frac {(r-l+1)(r-l+2)}{2}$,除以2可以留在外面做。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ol
    using namespace std;
    typedef long long ll;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int N=2e5+5;
    int n,fa[N],a[N],pos[N];
    int to[N<<1],head[N],nxt[N<<1],tot;
    ll v[N],ans;
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    int root[N],type,lp[N*30],rp[N*30],ls[N*30],rs[N*30];
    ll w[N*30];
    void up(int k,int l,int r)
    {
        int mid=l+r>>1;
        lp[k]=lp[ls[k]];rp[k]=rp[rs[k]];
        w[k]=w[ls[k]]+w[rs[k]];
        if(rp[ls[k]]&&lp[rs[k]])
        {
            w[k]-=1LL*(mid-rp[ls[k]]+1)*(mid-rp[ls[k]]+2)+1LL*(lp[rs[k]]-mid)*(lp[rs[k]]-mid+1);
            w[k]+=1LL*(lp[rs[k]]-rp[ls[k]]+1)*(lp[rs[k]]-rp[ls[k]]+2);
        }
        if(lp[ls[k]]==mid)lp[k]=lp[rs[k]]?lp[rs[k]]:mid;
        if(rp[rs[k]]==mid+1)rp[k]=rp[ls[k]]?rp[ls[k]]:mid+1;
    }
    void update(int &k,int l,int r,int pos)
    {
        if(!k)k=++type;
        if(l==r)
        {
            lp[k]=rp[k]=l;w[k]=2;
            return ;
        }
        int mid=l+r>>1;
        if(pos<=mid)update(ls[k],l,mid,pos);
        else update(rs[k],mid+1,r,pos);
        up(k,l,r);
    }
    int merge(int x,int y,int l,int r)
    {
        if(!x||!y)return x+y;
        if(l==r)return x;
        int mid=l+r>>1;
        ls[x]=merge(ls[x],ls[y],l,mid);
        rs[x]=merge(rs[x],rs[y],mid+1,r);
        up(x,l,r);
        return x;
    }
    void dfs(int x)
    {
        update(root[x],1,n,pos[x]);
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            dfs(y);
            merge(root[x],root[y],1,n);
        }
        ans+=w[root[x]]/2*v[x];
    }
    int main()
    {
    #ifdef ol
        freopen("sagittarius.in","r",stdin);
        freopen("sagittarius.out","w",stdout);
    #endif
        n=read();
        for(int i=2;i<=n;i++)
        {
            fa[i]=read();
            add(fa[i],i);
        }
        for(int i=1;i<=n;i++)
            a[i]=read(),pos[a[i]]=i;
        for(int i=1;i<=n;i++)
            v[i]=read();
        for(int i=n;i;i--)
            v[i]-=v[fa[i]];
        dfs(1);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    requestAnimationFrame
    react 面试题
    useState使用和原理
    常用网址记录
    .net 学习官网
    centos nginx 设置开启启动
    Asp.Net Core 发布和部署 Linux + Nginx
    SQL Server 执行计划缓存
    SQL Server之索引解析(二)
    SQL Server之索引解析(一)
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11768179.html
Copyright © 2011-2022 走看看