zoukankan      html  css  js  c++  java
  • ZJU-Summer Camp Problem

    Day 1

    NTT

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define m_k make_pair
    #define mod 998244353
    #define int long long
    using namespace std;
    const int N=4*1e5+100;
    int n,l,c,len,inv[N],rev[N],f[N],g[N];
    int fac[N];
    inline int m_pow(int a,int b)
    {
        a%=mod;
        int ans=1;
        while (b)
        {
            if (b&1) ans=(ans*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return ans;
    }
    inline void change(int len)
    {
        for (int i=0;i<len;i++)
        {
            rev[i]=rev[i>>1]>>1;
            if (i&1) rev[i]|=len>>1;
        }
    }
    inline int ntt(int y[],int len,int v)
    {
        for (int i=0;i<len;i++) if (i<rev[i]) swap(y[i],y[rev[i]]);
        for (int i=2;i<=len;i<<=1)
        {
            int step=m_pow(3,(mod-1)/i);
            if (v==-1) step=m_pow(step,mod-2);
            for (int j=0;j<len;j+=i)
            {
                int x=1;
                for (int k=j;k<j+i/2;k++)
                {
                    int a=y[k],b=(x*y[k+i/2])%mod;
                    y[k]=(a+b)%mod;
                    y[k+i/2]=(a-b+mod)%mod;
                    x=(x*step)%mod;
                }
            }
        }
        if (v==-1)
        {
            int invlen=m_pow(len,mod-2);
            for (int i=0;i<len;i++) y[i]=(y[i]*invlen)%mod; 
        }
    }
    signed main()
    {
        scanf("%lld%lld%lld",&n,&l,&c);
        c%=mod;
        if (c==1)
        {
            for (int i=1;i<=n;i++) printf("%lld
    ",l%mod);
            return 0;
        }
        fac[0]=1;
        for (int i=1;i<=n;i++) fac[i]=(fac[i-1]*i)%mod;
        inv[n]=m_pow(fac[n],mod-2);
        for (int i=n-1;i>=0;i--) inv[i]=(inv[i+1]*(i+1))%mod;
        len=1;
        while (len<=2*n) len<<=1;
        int invc=m_pow(c,mod-2);
        for (int i=0;i<=n;i++)
        {
            f[i]=inv[i];
            if (i==1) f[i]=(f[i]*l)%mod;
            else
            {
                int tmp;
                if (i==0) tmp=c;
                else tmp=m_pow(invc,i-1);
                f[i]=(f[i]*tmp)%mod;
                f[i]=(f[i]*(1-m_pow(tmp,l)+mod)%mod)%mod;
                f[i]=(f[i]*m_pow(1-tmp+mod,mod-2))%mod;
            }
            if (i&1) f[i]=(mod-f[i])%mod;
        }
        change(len);
        ntt(f,len,1),ntt(g,len,1);
        for (int i=0;i<len;i++) f[i]=(f[i]*g[i])%mod;
        ntt(f,len,-1);
        int ret=c;
        ret=(ret*(1-m_pow(c,l)+mod)%mod)%mod;
        ret=(ret*m_pow(1-c+mod,mod-2))%mod;
        for (int i=1;i<=n;i++) f[i]=(ret-(f[i]*fac[i])%mod+mod)%mod;
        int ans=0;
        for (int i=1;i<=n;i++) printf("%lld
    ",f[i]);
    }
    二分套二分
    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define m_k make_pair
    #define int long long
    using namespace std;
    const int N=2*1e5+100;
    int n,m,w,b[N],vi[N],h[N],k;
    int MAX,f[N][21],lg[N];
    long long si[N],sum[N],ans;
    struct node
    {
        int l,r,L,R,id;
    }sh[N];
    node a[N],c[N];
    inline int min(int a,int b){return((a<b)?a:b);}
    inline int max(int a,int b){return((a>b)?a:b);}
    inline int read()
    {
        int f=1,x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    bool cmp(node a,node b)
    {
        return (a.L<b.L || (a.L==b.L && a.R<b.R));
    }
    bool cmp1(node a,node b)
    {
        return (a.l<b.l || (a.l==b.l && a.r<b.r));
    }
    namespace tree
    {
        int sh[N];
        inline int lowbit(int x){return(x&(-x));}
        inline void change(int x,int v)
        {
            while (x>0)
            {
                sh[x]+=v;
                x-=lowbit(x);
            }
        }
        inline int query(int x)
        {
            int ans=0;
            while (x<=w)
            {
                ans+=sh[x];
                x+=lowbit(x);
            }
            return ans;
        }
    }
    inline void uni()
    {
        int r=n;n=0;
        for (int i=1;i<=r;)
        {
            c[++n]=sh[i];
            int j=i;
            while (j<=r && sh[i].L==sh[j].L && sh[i].R==sh[j].R) j++;
            i=j;
        }
        for (int i=1;i<=n;i++) sh[i]=c[i];
    }
    inline int get(int l,int r)
    {
        int len=r-l+1,p=lg[len];
        return max(f[l][p],f[r-(1<<p)+1][p]);
    }
    inline int find_l(int i){return lower_bound(h+1,h+1+k,a[i].l)-h;}
    inline int find_r(int i){return upper_bound(h+1,h+1+k,a[i].r)-h-1;}
    signed main()
    {
        m=read(),n=read();
        for (int i=1;i<=n;i++)
        {
            sh[i].l=read(),sh[i].r=read();
            b[++w]=sh[i].l,b[++w]=sh[i].r;
        }
        sort(b+1,b+1+w);
        w=unique(b+1,b+1+w)-b-1;
        for (int i=1;i<=n;i++)
        {
            sh[i].L=lower_bound(b+1,b+1+w,sh[i].l)-b;
            sh[i].R=lower_bound(b+1,b+1+w,sh[i].r)-b;
            sh[i].id=i;
        }
        sort(sh+1,sh+1+n,cmp);
        uni();
        for (int i=1;i<=n;)
        {
            int j=i;
            while (j<=n && sh[j].L==sh[i].L)
            {
                tree::change(sh[j].R,1);
                j++;
            }
            for (int k=i;k<j;k++)
            {
                tree::change(sh[k].R,-1);
                if (tree::query(sh[k].R)!=0) vi[k]=1;
                tree::change(sh[k].R,1);
            }
            i=j;
        }
        w=0;
        for (int i=1;i<=n;i++) if (!vi[i]) a[++w]=sh[i];
        sort(a+1,a+1+w,cmp1);
        for (int i=1;i<=w;i++) f[i][0]=a[i].r-a[i].l,lg[i]=log(i)/log(2);
        for (int j=1;j<=20;j++)
        {
            for (int i=1;i<=w;i++)
            {
                if (i+(1<<j)-1>w) break;
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            }
        }
        while (m--)
        {
            ans=0;
            k=read();
            for (int i=1;i<=k;i++) h[i]=read();
            sort(h+1,h+1+k);
            for (int i=1;i<=k;i++) si[i]=si[i-1]+1ll*i*h[i],sum[i]=sum[i-1]+h[i];
            for (int i=1;i<=w;)
            {
                int l=i,r=w,nowl=find_l(i),nowr=find_r(i);
                while (l<r)
                {
                    int mid=l+((r-l+1)>>1);
                    if (find_l(mid)==nowl && find_r(mid)==nowr) l=mid;
                    else r=mid-1;
                }
                ans=max(ans,1ll*get(i,l)+si[nowr]-si[nowl-1]-1ll*(nowl-1)*(sum[nowr]-sum[nowl-1]));
                i=l+1;
            }
            printf("%lld
    ",ans);
        }
    }

    广义SAM

    wqs二分+随机化扰动

    #include <bits/stdc++.h>
    #define mod 1000000007
    #define inv2 500000004
    #define int long long
    using namespace std;
    const int N=4641588,M=1e5+100;
    int n,phi[N+100],v[N+100],p[N],w;
    unordered_map <int,int> get_phi;
    int getphi(int n)
    {
        if (n<=N) return phi[n];
        if (get_phi[n]) return get_phi[n];
        int ans=((n%mod)*((n+1)%mod))%mod;
        ans=(ans*inv2)%mod;
        for (int l=2,r;l<=n;l=r+1)
        {
            r=n/(n/l);
            ans=(ans-getphi(n/l)*((r-l+1)%mod)%mod+mod)%mod;
        }
        get_phi[n]=ans;
        return ans;
    }
    inline int f(int n)
    {
        return (2*getphi(n)%mod-1+mod)%mod;
    }
    signed main()
    {
        scanf("%lld",&n);
        phi[1]=1;
        for (int i=2;i<=N;i++)
        {
            if (!v[i])
            {
                v[i]=i,p[++w]=i;
                phi[i]=i-1;
            }
            for (int j=1;j<=w;j++)
            {
                if (p[j]>v[i] || p[j]>N/i) break;
                v[p[j]*i]=v[i];
                if (i%p[j]==0) phi[i*p[j]]=(phi[i]*p[j])%mod;
                else phi[i*p[j]]=(phi[i]*(p[j]-1))%mod;
            }
        }
        for (int i=1;i<=N;i++) phi[i]=(phi[i]+phi[i-1])%mod;
        int ans=0;
        for (int l=1,r;l<=n;l=r+1)
        {
            r=n/(n/l);
            ans=(ans+((getphi(r)-getphi(l-1)+mod)%mod*f(n/l))%mod)%mod;
        }
        printf("%lld
    ",ans);
    }

     LCT

    #include <bits/stdc++.h>
    using namespace std;
    const int N=3*1e5+100;
    int n,m,son[N][2],fa[N],tag[N],root;
    int sz[N],place[N],now,realson[N],minde[N];
    int tot,first[N],nxt[N*2],point[N*2];
    struct node
    {
        int val,id;
    }sh[N];
    long long ret,ans,val[N],sum[N];
    inline void add_edge(int x,int y)
    {
        tot++;
        nxt[tot]=first[x];
        first[x]=tot;
        point[tot]=y;
    }
    inline int read()
    {
        int f=1,x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        x*=f;
        return x;
    }
    inline int sf(int x)
    {
        return (son[fa[x]][1]==x);
    }
    inline bool nroot(int x)
    {
        return (son[fa[x]][0]==x||son[fa[x]][1]==x);
    }
    inline void rev(int x)
    {
        swap(son[x][0],son[x][1]);
        tag[x]^=1;
    }
    inline void pushup(int x)
    {
        sum[x]=sum[son[x][0]]+sum[son[x][1]]+val[x];
        if (son[x][0]) minde[x]=minde[son[x][0]];
        else minde[x]=x;
    }
    inline void pushdown(int x)
    {
        if (tag[x])
        {
            if (son[x][0]) rev(son[x][0]);
            if (son[x][1]) rev(son[x][1]);
            tag[x]=0;
        }
    }
    inline void pushall(int x)
    {
        if (nroot(x)) pushall(fa[x]);
        pushdown(x);
    }
    inline void connect(int x,int y,int dir)
    {
        son[y][dir]=x;
        fa[x]=y;
    }
    inline void rotate(int x)
    {
        int f,gf,xd,fd,s;
        f=fa[x],gf=fa[f],xd=sf(x),fd=sf(f),s=son[x][xd^1];
        if (nroot(f)) connect(x,gf,fd);
        connect(f,x,xd^1);
        if (s) connect(s,f,xd);
        fa[x]=gf,son[f][xd]=s;
        pushup(f),pushup(x);
    }
    inline void splay(int x)
    {
        pushall(x);
        while (nroot(x))
        {
            if (!nroot(fa[x])) rotate(x);
            else if (sf(fa[x])==sf(x)) rotate(fa[x]),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    inline void access(int x)
    {
        for (int y=0;x;x=fa[x])
        {
            splay(x);
            son[x][1]=y;
            if (y==0) realson[x]=0;
            else realson[x]=minde[y];
            if (place[x]<=now) val[x]=n-sz[x]-sz[minde[y]];
            pushup(x);
            y=x;
            root=x;
        }
    }
    inline void makeroot(int x)
    {
        access(x);
        splay(x);
        rev(x);
    }
    inline int findroot(int x)
    {
        access(x);
        splay(x);
        while (son[x][0]) pushdown(x),x=son[x][0];
        splay(x);
        return x;
    }
    inline void link(int x,int y)
    {
        makeroot(x);
        if (findroot(y)!=x) fa[x]=y;
    }
    void dfs(int x,int fa)
    {
        if (x!=1) link(x,fa);
        sz[x]=1;
        for (int i=first[x];i!=-1;i=nxt[i])
        {
            int u=point[i];
            if (u==fa) continue;
            dfs(u,x);
            sz[x]+=sz[u];
        }
    }
    inline bool cmp(node a,node b)
    {
        return a.val>b.val;
    }
    int main()
    {
        tot=-1;
        memset(first,-1,sizeof(first));
        memset(nxt,-1,sizeof(nxt));
        n=read();
        for (int i=1;i<=n;i++) sh[i].val=read(),sh[i].id=i,minde[i]=i;
        sort(sh+1,sh+1+n,cmp);
        for (int i=1;i<=n;i++) place[sh[i].id]=i;
        for (int i=1;i<n;i++)
        {
            int u,v;
            u=read(),v=read();
            add_edge(u,v);
            add_edge(v,u);
    //        link(u,v);
        }
        dfs(1,1);makeroot(1);
        for (int i=1;i<=n;)
        {
    //        if (minde[0]!=0) printf("OK
    ");
            now=i-1;
            int j=i;
            while (j<=n && sh[i].val==sh[j].val)
            {
                access(sh[j].id);
                ans+=ret+sum[root];
                j++;
            }
            for (int k=i;k<j;k++)
            {
                int x=sh[k].id;
                ret+=sz[x];
                if (realson[x]!=0)
                {
                    splay(x);
                    val[x]=n-sz[x]-sz[realson[x]];
                    pushup(x);
                }
            }
            i=j;
        }
        printf("%lld
    ",ans);
    }

    主席树

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    typedef long long ll;
    typedef unsigned un;
    typedef std::string str;
    typedef std::pair<ll,ll> pll;
    ll read(){ll x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return f*x;}
    ll max(ll a,ll b){return a>b?a:b;}
    void umax(ll& a,ll t){if(t>a)a=t;}
    const ll INF=1ll<<58;
    #define MAXN 300011
    ll diff,fx[MAXN],a[MAXN],c=0;
    ll place(ll val){return std::lower_bound(fx+1,fx+diff+1,val)-fx;}
    struct Edge
    {
        ll v,nxt;
    }e[MAXN<<1|1];
    ll ecnt=0,last[MAXN];
    void adde(ll u,ll v)
    {
        ++ecnt;
        e[ecnt].v=v;
        e[ecnt].nxt=last[u],last[u]=ecnt;
    }
    ll dfn[MAXN],ed[MAXN],w[MAXN],fa[MAXN], cur=0;
    void dfs(ll u)
    {
        dfn[u]=++cur;w[cur]=a[u];
        for(ll i=last[u];i;i=e[i].nxt)
        {
            ll v=e[i].v;
            if(v==fa[u])continue;
            fa[v]=u;
            dfs(v);
        }
        ed[u]=cur;
    }
    struct node
    {
        ll sum;
        int lson,rson;
    }t[MAXN<<5|1];
    int root[MAXN],cnt=0,n;
    #define rt t[num]
    void insert(int pre,int& num,un pos,un l=1,un r=diff)
    {
        num=++cnt;
        rt=t[pre],++rt.sum;
        if(l==r)return;
        un mid=(l+r)>>1;
        if(pos<=mid)insert(t[pre].lson,rt.lson,pos,l,mid);
        else insert(t[pre].rson,rt.rson,pos,mid+1,r);
    }
    void Qsum(int pre,int num,un pos,un l=1,un r=diff)
    {
        if(!pos)return;
        if(l==r){c+=rt.sum-t[pre].sum;return;}
        un mid=(l+r)>>1;
        
        if(pos<=mid)Qsum(t[pre].lson,rt.lson,pos,l,mid);
        else
        {
            c+=t[rt.lson].sum-t[t[pre].lson].sum;
            Qsum(t[pre].rson,rt.rson,pos,mid+1,r);
        }
    }
    
    int main()
    {
        n=read();
        for(ll i=1;i<=n;++i)fx[++diff]=a[i]=read();
        std::sort(fx+1,fx+diff+1),diff=std::unique(fx+1,fx+diff+1)-fx-1;
        for(ll i=1;i<n;++i){ll u=read(),v=read();adde(u,v),adde(v,u);}
        dfs(1);
        for(ll i=1;i<=n;++i)w[i]=place(w[i]),insert(root[i-1],root[i],w[i]);
        ll ans=0;
        for(ll u=1;u<=n;++u)
        {
            for(ll i=last[u];i;i=e[i].nxt)
            {
                ll v=e[i].v;
                if(v==fa[u])
                {
                    c=0;
                    Qsum(root[0],root[dfn[u]-1],w[dfn[u]]-1),Qsum(root[ed[u]],root[n],w[dfn[u]]-1);
                    ans+=c*(ed[u]-dfn[u]+1);
                    continue;
                }
                c=0;
                Qsum(root[dfn[v]-1],root[ed[v]],w[dfn[u]]-1);
                //printf("%lld nodes in sub(%lld)
    ",c,v);
                ans+=c*(n-(ed[v]-dfn[v]+1));
            }
        }
        printf("%lld",ans);
        return 0;
    }

    树状数组

    #include <algorithm>
    #include <cassert>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    #include <vector>
    #define m_p make_pair
    #define sz(x) (int)x.size()
    #define out(x) cerr<<#x<<" = "<<x<<" "
    #define outln(x) cerr<<#x<<" = "<<x<<endl
    #define outarr(x,l,r) cerr<<#x"["<<l<<"-"<<r<<"] = "; for (int _i=l;_i<=r;++_i) cerr<<x[_i]<<" ";cerr<<endl;
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define gc() getchar()
    //char buf[1<<23],*p1=buf,*p2=buf;
    //#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    template <class T> void read(T &x)
    {
        x=0; char c=gc(); int flag=0;
        while (c<'0'||c>'9') flag|=(c=='-'),c=gc();
        while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=gc();
        if (flag) x=-x;
    }
    template <class T> T _max(T a,T b){return a>b ? a : b;}
    template <class T> T _min(T a,T b){return a<b ? a : b;}
    template <class T> bool checkmax(T &a,T b){return b>a ? a=b,1 : 0;}
    template <class T> bool checkmin(T &a,T b){return b<a ? a=b,1 : 0;}
    const int N=300005;
    int n,a[N],sz[N],dfn[N],dfs_clock=0,p[N],fa[N];
    vector <int> G[N];
    void add_edge(int x,int y)
    {
        G[x].push_back(y);
    }
    
    void dfs(int x,int f)
    {
        sz[x]=1; dfn[x]=++dfs_clock; fa[x]=f;
        for (int i=0;i<sz(G[x]);++i)
        {
            int to=G[x][i];
            if (to==f) continue;
            dfs(to,x);
            sz[x]+=sz[to];
        }
    }
    
    void init()
    {
        read(n);
        for (int i=1;i<=n;++i)
        {
            read(a[i]);
        }
        for (int i=1,u,v;i<n;++i)
        {
            read(u); read(v);
            add_edge(u,v);
            add_edge(v,u);
        }
        dfs(1,0);
    }
    
    bool cmp(int x,int y){return a[x]<a[y];}
    namespace BIT
    {
        int C[N];
        void update(int x,int num)
        {
            for (;x<=n;x+=(x&(-x))) C[x]+=num;
        }
        
        int query(int x)
        {
            int ans=0;
            for (;x;x-=(x&(-x))) ans+=C[x];
            return ans;
        }
        
        int query(int l,int r)
        {
            return query(r)-query(l-1);
        }
    }
    
    void solve()
    {
        ll ans=0;
        for (int i=1;i<=n;++i) p[i]=i;
        sort(p+1,p+n+1,cmp);
        for (int i=1,pre=0;i<=n;++i)
        {
            int x=p[i];
            for (int j=0;j<sz(G[x]);++j)
            {
                int to=G[x][j];
                if (to!=fa[x])
                {
                    ans+=(ll)BIT::query(dfn[to],dfn[to]+sz[to]-1)*(n-sz[to]);
                }
                else
                {
                    ans+=(ll)(BIT::query(1,n)-BIT::query(dfn[x],dfn[x]+sz[x]-1))*sz[x];
                }
            }
            if (a[p[i]]==a[p[i+1]]) continue;
            for (int j=pre+1;j<=i;++j)
            {
                BIT::update(dfn[p[j]],1);
            }
            pre=i;
        }
        printf("%lld
    ",ans);
    }
     
    int main()
    {
        init();
        solve();
        return 0;
    }
  • 相关阅读:
    js中连续赋值
    PHP文件上传漏洞原理以及如何防御详解 【转】
    奇虎360PHP工程师2019年面试题和答案解析【转】
    学习ES6碰到的单词
    Proxy(代理)例子
    for of 迭代器 生成器 数组的一些杂乱记录
    async和await
    Promise.call
    ES6中Promise.race
    Promise 和.then
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/13324641.html
Copyright © 2011-2022 走看看