• 简单的题目 专题


    挖坑

    总是要填的

    可是我不填

    哎呀真香!

    水题1

     既然是简单的题目,那当然是放大水题辣

    只有a,b  的二进制的每一个1位置都不同时a&b ==0 

     所以随便维护一下每个数二进制有1位的序列最大值就行了QAQ

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N=100000+10;
    int a[N],dp[N],s[60],ans,n;
     
    void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
     
    int main(){
        read(n);
        for(int i=1;i<=n;i++) read(a[i]);
        for(int i=1;i<=n;i++){
            int x=a[i],mx=0,t=0;
            while(x){
                ++t;
                if(x%2) mx=max(mx,s[t]);
                x/=2;
            }
            dp[i]=mx+1;
            x=a[i];t=0;
            while(x){
                ++t;
                if(x%2) s[t]=max(s[t],dp[i]);
                x/=2;
            }
            ans=max(ans,dp[i]);
        }
        printf("%d",ans);
        return 0;
    }
    
    View Code

    水题2 

     既然是简单的题目,那当然是放大水题辣

    正反hash,暴力枚举串o1判断

    剪枝:ans*k如果大于n,显然不比当前答案更优

    #include <iostream>
    #include <cstdio>
    #include <map>
    #define ull unsigned long long
    using namespace std;
    const int base=19260817;
    const int N=200000+10;
    int n,a[N];
    ull b[N],hs1[N],hs2[N];
    map<ull,bool>mp;
    //set<ull>se;
    
    void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
    
    void read(ull &x){
        x=0;ull f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
    
    int st[N],top;
    int main(){
        read(n);
        for(register int i=1;i<=n;i++) read(a[i]);
        b[0]=1;
        for(register int i=1;i<=n;i++) b[i]=b[i-1]*base;
        for(register int i=1;i<=n;i++) hs1[i]=hs1[i-1]*base+a[i];
        for(register int i=n;i;i--) hs2[i]=hs2[i+1]*base+a[i];
        int ans=0;
        for(register int i=1;i<=n;i++){
            int s=0;
            mp.clear();
            ull h,f;
            for(register int j=i;j<=n;j+=i){
                if(ans*i>n) break;
                h=hs1[j]-hs1[j-i]*b[i];
                f=hs2[j-i+1]-hs2[j+1]*b[i];
    //            se.insert(h);
    //            se.insert(f);
    //            if(se.size()!=s) s++;
    //            if(i==1) cout<<b[i]<<' ';
                if((!mp.count(h))&&(!mp.count(f))){
                    s++;
                    mp[h]=mp[f]=1;
                }
             }
             if(s>ans){
                 ans=s;
                 st[top=1]=i;
             }
             else if(s==ans) st[++top]=i;
    //         if(i==2) cout<<s<<' 
        }
        printf("%d %d
    ",ans,top);
        for(register int i=1;i<=top;i++) printf("%d ",st[i]);
        return 0;
    }
    View Code

     水题3

    CDQ分治。。。

    KD-Tree 应该也

    那个啥有一个小点忘记讲了QAQ

    x和y的值都很大,如果用BIT维护x或y轴显然是不太优的

    所以要把x或y离散化

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <map>
    #define ll long long
    using namespace std;
    const int N=2500000+10;
    ll n,m,ans[N],cnt,tot,bt[N*2];
    map<ll,ll>mp;
    struct nod{
        ll x,y,id,val,opt;
        bool operator < (const nod&a) const {
            return x<a.x;
        }
    }a[N];
    struct tre{
        ll x,y;
        bool operator < (const tre&a) const {
            return y<a.y;
        }
    }t[N];
    
    void read(ll &x){
        x=0;ll f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
    
    ll lowbit(ll x){
        return x&(-x);
    }
    
    void update(ll x,ll v){
        for(ll i=x;i<=cnt;i+=lowbit(i)) bt[i]+=v;
    }
    
    ll query(ll x){
        ll ans=0;
        for(ll i=x;i;i-=lowbit(i)) ans+=bt[i];
        return ans;
    }
    
    nod q[N];
    void cdq(ll l,ll r){
        if(l==r) return ;
        ll mid=(l+r)/2;
        cdq(l,mid);
        cdq(mid+1,r);
        int qwq=l-1,l1=l,l2=(l+mid)/2+1,m1=(l+mid)/2;
        while(l1<=m1&&l2<=mid){
            if(a[l2]<a[l1]) q[++qwq]=a[l2++];
            else q[++qwq]=a[l1++]; 
        }
        while(l1<=m1) q[++qwq]=a[l1++];
        while(l2<=mid) q[++qwq]=a[l2++];
        l1=mid+1;m1=(mid+1+r)/2;l2=m1+1;
        while(l1<=m1&&l2<=r){
            if(a[l2]<a[l1]) q[++qwq]=a[l2++];
            else q[++qwq]=a[l1++]; 
        }
        while(l1<=m1) q[++qwq]=a[l1++];
        while(l2<=r) q[++qwq]=a[l2++];
        for(int i=l;i<=r;i++) a[i]=q[i];
        ll j=l;
        for(ll i=mid+1;i<=r;i++){
            for(;j<=mid&&a[j].x<=a[i].x;j++)
                if(!a[j].opt) update(a[j].y,a[j].val);
    //        cout<<1;
            if(a[i].opt) ans[a[i].id]+=a[i].val*query(a[i].y);
        }
        for(ll i=l;i<j;i++)
            if(!a[i].opt) update(a[i].y,-a[i].val);
    }
    
    ll b[N],aa[N],bc;
    int main(){
    //    freopen("QAQQWQ.in","r",stdin);
        read(n);read(m);
        for(ll i=1;i<=n;i++) read(t[i].x),read(t[i].y);
        sort(t+1,t+1+n);
        aa[0]=-1;
        for(ll i=1;i<=n;i++) aa[++bc]=t[i].y+1;
        for(ll i=1;i<=n;i++) a[++tot]=(nod){t[i].x+1,t[i].y+1,0,1,0};
        for(ll i=1;i<=m;i++){
            ll x1,x2,y1,y2;
            read(x2);read(y2);
            read(x1);read(y1);
            ++x2;++x1;++y1;++y2;
            a[++tot]=(nod){x1,y1,i,1,1};
            a[++tot]=(nod){x2-1,y2-1,i,1,1};
            a[++tot]=(nod){x1,y2-1,i,-1,1};
            a[++tot]=(nod){x2-1,y1,i,-1,1};
            aa[++bc]=y1;aa[++bc]=y2-1;
        }
        sort(aa+1,aa+1+bc);
        for(ll i=1;i<=bc;i++)
            if(aa[i]!=aa[i-1]) b[++cnt]=aa[i],mp[aa[i]]=cnt;
        for(ll i=1;i<=tot;i++) a[i].y=mp[a[i].y];
        cdq(1,tot);
        for(ll i=1;i<=m;i++) printf("%lld
    ",ans[i]);
        return 0;
    }
    View Code

    水题4

    QAQ不会写...

    容易发现有三种跳法 向两边往外跳 向内跳

    会发现 这世上可以看成一棵树 

    于是答案变成了两个节点间的距离

    很遗憾如果我们直接求lca是不可行的

    不过我们可以考虑让一个节点爬到和另一节点同一深度处

    这直接除出跳的深度

    这样的话效率就大大提高了,gcd?

    这样来看我们可以二分节点爬的深度来解决这个问题

    应该是这样?

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    int a[5],b[5],v,ans;
    struct QAQ{
        int a[5];
        bool operator != (const QAQ&x) const {
            return !(x.a[3]==a[3]&&x.a[1]==a[1]&&x.a[2]==a[2]);
        }
    };
    
    void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
    
    QAQ calc(int a[],int k){
        QAQ ans;
        int t1=a[2]-a[1],t2=a[3]-a[2];
        for(int i=1;i<=3;i++) ans.a[i]=a[i];
        if(t1==t2) return ans;
        if(t1>t2){
            int t=min(k,(t1-1)/t2);
            k-=t;v+=t;
            ans.a[2]-=t*t2;
            ans.a[3]-=t*t2;
        }
        else {
            int t=min(k,(t2-1)/t1);
            k-=t;v+=t;
            ans.a[2]+=t*t1;
            ans.a[1]+=t*t1;
        }
        if(k) return calc(ans.a,k);
        else return ans;
    }
    
    int main(){
        for(int i=1;i<=3;i++) read(a[i]);
        for(int i=1;i<=3;i++) read(b[i]);
        sort(a+1,a+4);sort(b+1,b+4);
        QAQ t1=calc(a,1000000000);int b1=v;v=0;
        QAQ t2=calc(b,1000000000);int b2=v;v=0;
        if(t1!=t2){
            printf("NO");
            return 0;
        }
        else printf("YES
    ");
        if(b1>b2){
            swap(b1,b2);
            swap(a,b);
        }
        ans=(b2-b1);
        t1=calc(b,ans);
        for(int i=1;i<=3;i++) b[i]=t1.a[i];
        int l=0,r=b2;
        while(l<r){
            int mid=(l+r)/2;
            if(calc(a,mid)!=calc(b,mid)) l=mid+1;
            else r=mid;
        }
        printf("%d",ans+2*r);
        return 0;
    }
    View Code

    水题5

    直接链表trie

    #include <iostream>
    #include <cstdio>
    #define ll long long
    using namespace std;
    const int N=5000000+10;
    int n,val[N],v[N],nxt[N],first[N],cnt,sz=1;
    ll ans;
    char w[N],c;
    
    void add(int a,int b,char c){
        v[++cnt]=b;
        nxt[cnt]=first[a];
        w[cnt]=c;
        first[a]=cnt;
    }
    
    void insert(){
        c=getchar();
        int u=0,t=1;
        while(c=='
    ') c=getchar();
        for(int i=1;c!='
    ';i++,c=getchar()){
            u=0;
            for(int j=first[t];j;j=nxt[j])
                if(w[j]==c){
                    u=v[j];
                    break;
                }
            if(!u) add(t,u=++sz,c);
            t=u;
            val[u]++;
            ans=max(ans,1ll*val[u]*1ll*i);
        }
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) insert();
        printf("%lld",ans);
        return 0;
    }
    View Code

    水题6

    世上这就是个基环树森林

    所以直接断边做树形dp

    dp[x][0/1]表示不选或选x的最大值

    dp[x][0]+=max{dp[son[x]][1],dp[son[x]][0]}

    dp[x][1]+=max{dp[son[x]][0]} 

    #include <iostream>
    #include <cstdio>
    #define ll long long
    using namespace std;
    const int N=1000000+10;
    int v[N*2],nxt[N*2],first[N],cnt=1;
    int n,m,val[N];
    ll ans,dp[N][2];
    bool vis[N],fl[N*2],QAQ;
    
    void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
    
    void add(int a,int b){
        v[++cnt]=b;
        nxt[cnt]=first[a];
        first[a]=cnt;
    }
    
    int s,t;
    void dfs(int x,int y){
        vis[x]=1;
        for(int i=first[x];i&&QAQ;i=nxt[i]){
            if(v[i]==y) continue;
            if(vis[v[i]]){
                fl[i]=fl[i^1]=1;
                s=x;t=v[i];
                QAQ=0;
                break;
            }
            else dfs(v[i],x);
        }
    }
    
    void getdp(int x,int y,int qwq){
        vis[x]=1;
        if(x==qwq) dp[x][1]=0ll;
        else dp[x][1]=(ll)val[x];
        dp[x][0]=0ll;
        for(int i=first[x];i;i=nxt[i]){
            if(y==v[i]||fl[i]) continue;
            getdp(v[i],x,qwq);
            dp[x][1]+=dp[v[i]][0];
            dp[x][0]+=max(dp[v[i]][1],dp[v[i]][0]);
        }
    }
    
    int main(){
        read(n);
        for(int i=1;i<=n;i++){
            read(val[i]);
            int x;
            read(x);
            add(x,i);
            add(i,x);
        }
        for(int i=1;i<=n;i++){
            if(vis[i]) continue;
            QAQ=1;
            ll mx=0;
            dfs(i,0);
            getdp(s,0,t);
            mx=max(dp[s][0],dp[s][1]);
            getdp(t,0,s);
            ans+=max(mx,max(dp[t][0],dp[t][1]));
        }
        printf("%lld",ans);
        return 0;
    }
    View Code

    水题7

    太久没填坑了,就随便放几道水题吧qwq

    随便推一下会发现 原式=∑nD=1 F(n/D,m/D)*G(D)

     其中 F(n,m)=(1+n)*n-n*(2n+1)(n+1)/3+n*(n+m+1)(m-n)/2-(m-n)(1+n)*n/2

        G(D)=∑k|D miu(k)*k

    #include <iostream>
    #include <cstdio>
    using namespace std;
    #define ll long long
    const int N=2000000+10;
    const int mod1=1000000000+7;
    const int mod2=mod1+2;
    int g1[N],g2[N],pri[N],cnt;
    int inv2,inv3,inv4,inv6;
    bool isp[N];
      
    void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        x*=f;
    }
      
    void euler(){
        g1[1]=g2[1]=1;
        isp[1]=1;
        for(int i=2;i<N;i++){
            if(!isp[i]){
                pri[++cnt]=i;
                g1[i]=((1-i)%mod1+mod1)%mod1;
                g2[i]=((1-i)%mod2+mod2)%mod2;
            }
            for(int j=1;j<=cnt&&i*pri[j]<N;j++){
                isp[i*pri[j]]=1;
                if(i%pri[j]==0){
                    g1[i*pri[j]]=g1[i];
                    g2[i*pri[j]]=g2[i];
                    break;
                }
                g1[i*pri[j]]=1ll*g1[i]*g1[pri[j]]%mod1;
                g2[i*pri[j]]=1ll*g2[i]*g2[pri[j]]%mod2;
            }
        }
        for(int i=1;i<N;i++) g1[i]=(g1[i-1]+1ll*g1[i])%mod1;
        for(int i=1;i<N;i++) g2[i]=(g2[i-1]+1ll*g2[i])%mod2;
    }
      
    int f1(int n,int m){
        return ((((((1ll*(1ll*(1+n)%mod1*n%mod1*n%mod1)-1ll*(1ll*(2*n+1)%mod1*n%mod1*(n+1)%mod1)*inv3%mod1)%mod1)+1ll*n*(n+m+1)%mod1*(m-n)%mod1*inv2%mod1)%mod1)-1ll*(m-n)*(1+n)%mod1*n%mod1*inv2%mod1)%mod1+mod1)%mod1;
    }
      
    int f2(int n,int m){
        return ((((((1ll*(1ll*(1+n)%mod2*n%mod2*n%mod2)-1ll*(1ll*(2*n+1)%mod2*n%mod2*(n+1)%mod2)*inv6%mod2)%mod2)+1ll*n*(n+m+1)%mod2*(m-n)%mod2*inv4%mod2)%mod2)-1ll*(m-n)*(1+n)%mod2*n%mod2*inv4%mod2)%mod2+mod2)%mod2;
    }
      
    int main(){
        inv2=500000004;
        inv3=333333336;
        inv4=500000005;
        inv6=666666673;
        euler();
        int t;
        read(t);
        while(t--){
            int n,m;
            read(n);read(m);
            if(n>m) swap(n,m);
            ll ans1=0,ans2=0;
            for(int l=1,r;l<=n;l=r+1){
                r=min(n/(n/l),m/(m/l));
                ans1=(ans1+1ll*f1(n/l,m/l)*(((1ll*g1[r]-g1[l-1])%mod1+mod1)%mod1)%mod1)%mod1;
                ans2=(ans2+1ll*f2(n/l,m/l)*(((1ll*g2[r]-g2[l-1])%mod2+mod2)%mod2)%mod2)%mod2;
            }
            printf("%lld %lld
    ",ans1,ans2);
        }
        return 0;
    }
    View Code

    【7/12】((๑°ㅁ°๑)ᵎᵎᵎ  怎么又多了

  • 相关阅读:
    Android 调用已安装市场,进行软件评分的功能实现
    二十六个月Android学习工作总结
    Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1) 错误 解决方案(android-ndk)
    【Android】神奇的android:clipChildren属性
    Android利用setLayoutParams在代码中调整布局(Margin和居中)
    android 使用代码实现 RelativeLayout布局
    Android 布局学习
    Erlang cowboy 处理不规范的client
    HTTP 响应
    把字符串转换为整数
  • 原文地址:https://www.cnblogs.com/lyf2/p/9497372.html
Copyright © 2020-2023  润新知