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;
    }
    
  • 相关阅读:
    Java B/S开发模式漫谈 (转)
    struts 使用多个配置文件 strutsconfig.xml
    java 验证邮箱格式正确性、验证字符串是否为数字
    Java获取各种常用时间方法
    创建HttpServlet的基本步骤
    struts1.x 配置文件之——web.xml详解
    最常用的JAVA包
    字符串转换为日期时间格式
    struts1.x 配置文件详解
    看看别人的博客,经验总结,很宝贵
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11768179.html
Copyright © 2011-2022 走看看