• 清北考前刷题day2早安


    /*
    做法一:按h sort一遍,对于一段区间[i,j],高度花费就是h[j]-h[i]
    然后枚举区间,把区间内C排序,一个一个尽量选即可。
    n^3logn
    标算:n^3 dp
    高度排序,保证从前往后调。
    f[i][j]表示当前在第i栋楼,已经跳了j次楼的最小话费。转移枚举下一次跳那座楼。
    f[k][j+1]=min(f[i][j],f[i][j]+h[k]-h[i]+c[k]);最后枚举f[i][j]<T,ans=max(ans,j)。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    #define N 510
    
    using namespace std;
    int T,n,ans,cnt;
    int f[N][N];//当前处于第i座楼房已经跳了j次楼最小花费 
    struct node{
        int h,c;
        bool operator < (const node a) const{
                return h<a.h;
        }
        
    }L[N];
    
    inline int read()
    { 
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) L[i].c=read();
        for(int i=1;i<=n;i++) L[i].h=read();
        T=read();
        sort(L+1,L+n+1);
        
        memset(f,127/3,sizeof f);
        f[1][0]=f[1][1]=L[1].c;
        for(int i=1;i<=n;i++)
          for(int j=0;j<=n+1;j++)
            for(int k=i+1;k<=n;k++)
              f[k][j+1]=min(f[k][j+1],f[i][j]+L[k].h-L[i].h+L[k].c);
                    
        for(int i=1;i<=n;i++)
          for(int j=0;j<=n+1;j++)
            if(f[i][j]<=T) ans=max(ans,j);
        printf("%d
    ",ans);
        return 0;
         
    }

     

     

     

    /*
    考虑最后要求的数 a1,a2,..an假定从小到大
    给定了b1,b2......bn 从小到大排序
    性质一:a1+a2=b1
    性质二:a1+a3=b2
    假设a2+a3=x,可以解出a1,a2,a3,并可以在b中b1,b2,x删除。则剩下的最小的一定是a1+a4。由于a1已知,a4可解。这个过程可以反复下去。
    枚举a2+a3=b里面哪个数就好
    */
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int N=310;
    
    int n,m,res[N],ans[N][N],z[N*N],cnt;
    
    bool use[N*N];
    
    void check(int p)
    {
        memset(use,false,sizeof(use));
        if ((z[1]+z[2]+z[p])&1) return;
        res[1]=(z[1]+z[2]+z[p])/2-z[p];
        res[2]=z[1]-res[1];
        res[3]=z[2]-res[1];
        use[1]=use[2]=use[p]=true;
        for (int a=4,b=3;a<=n;a++)
        {
            while (b<=m && use[b]) b++;
            if (b>m) return;
            res[a]=z[b]-res[1];
            use[b]=true;
            for (int c=2;c<a;c++)
            {
                if (res[c]>res[a]) return;
                int v=res[c]+res[a];
                int p=lower_bound(z+1,z+m+1,v)-z;
                if (z[p]!=v) return;
                int px=p;
                while (px && z[px]==z[p]) px--;
                px++;
                while (px<=m && z[px]==z[p] && use[px]) px++;
                if (z[px]!=z[p] || use[px]) return;
                p=px;    use[p]=true;
            }
        }
        cnt++;
        for (int a=1;a<=n;a++) ans[cnt][a]=res[a];
    }
    
    int main()
    {
        freopen("city.in","r",stdin);
        freopen("city.out","w",stdout);
        scanf("%d",&n);
        m=n*(n-1)/2;
        for (int a=1;a<=m;a++) scanf("%d",&z[a]);
        sort(z+1,z+m+1);
        for (int a=3;a<=m;)
        {
            check(a);int b=a;
            while (b<=m && z[b]==z[a])b++;
            a=b;
        }
        printf("%d
    ",cnt);
        for (int a=1;a<=cnt;a++)
            for (int b=1;b<=n;b++)
            {
                printf("%d",ans[a][b]);
                if (b==n) printf("
    ");
                else printf(" ");
            }
        return 0;
    }

     

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    
    #define N 100007
    
    using namespace std;
    int n,m,ans,c,p,v;
    int a[N];
    vector<int>sum[N];
    struct ask{
        int l,r,v,p;
    }A[N];
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        freopen("light.in","r",stdin);
        freopen("light.out","w",stdout);
        int l,r;
        n=read();m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        if(n<=1000)
        {
            for(int i=1;i<=m;i++)
            {
                ans=0;
                l=read();r=read();p=read();v=read();
                for(int j=l;j<=r;j++) if(a[j]%p==v) ans++;
                printf("%d
    ",ans);
            }        
        }
        else
        {
            for(int i=1;i<=m;i++)
            {
                A[i].l=read();A[i].r=read();
                A[i].p=read();A[i].v=read();
            }    
            for(int i=1;i<=n;i++) a[i]%=A[1].p;
            for(int i=1;i<=n;i++) 
              sum[a[i]].push_back(i);
            for(int i=1;i<=m;i++)
            {
                printf ("%d
    ",upper_bound(sum[A[i].v].begin (), sum[A[i].v].end (), A[i].r) 
                -lower_bound (sum[A[i].v].begin (), sum[A[i].v].end (), A[i].l)); 
            }
        }
        return 0;
    }
    60暴力

    链表?!!wt?!
    可以对p分块 。
    p在[1,10^4+1]。如果枚举p预处理每个数mod p扔到vector里。O(np) TLE
    可以把p在[1,100]里预处理,vector里二分即可。
    p>100时,只有v+p,v+2p...v+kp能对答案造成贡献。一定有v+kp<=10^4,p>100-->k<=100。所以每次询问都最多有100个数对答案造成贡献,可以vector预处理,枚举这100个v+jp,vector里二分。
    复杂度n*sqrt(n)*lgn。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100009;
    const int maxv = 10000;
    const int bsz = 100;
    const int maxb = 103;
    
    int n, m;
    int a[maxn], vb[maxb][maxb], ve[maxb][maxb];
    int xb[maxn], xe[maxn];
    int i_buf[maxn * maxb * 2], tib;
    
    void pre() {
        memset(ve, 0, sizeof(ve));
        memset(xe, 0, sizeof(xe));
        for (int i = 1; i <= n; ++ i)
            ++ xe[a[i]];
        for (int i = 0; i <= maxv; ++ i) {
            xb[i] = tib;
            tib += xe[i];
            xe[i] = xb[i];
        }
        for (int i = 1; i <= n; ++ i)
            i_buf[xe[a[i]] ++] = i;
        for (int m = 1; m <= bsz; ++ m) {
            for (int i = 1; i <= n; ++ i)
                ++ ve[m][a[i] % m];
            for (int i = 0; i < m; ++ i) {
                vb[m][i] = tib;
                tib += ve[m][i];
                ve[m][i] = vb[m][i];
            }
            for (int i = 1; i <= n; ++ i)
                i_buf[ve[m][a[i] % m] ++] = i;
        }
    }
    
    int queryb(int l0, int r0, int p, int k) {
        if (vb[p][k] == ve[p][k])
            return 0;
        int *x1 = lower_bound(i_buf + vb[p][k], i_buf + ve[p][k], l0);
        int *x2 = upper_bound(i_buf + vb[p][k], i_buf + ve[p][k], r0);
        return x2 - x1;
    }
    
    int querys(int v, int l0, int r0) {
        if (xb[v] == xe[v])
            return 0;
        int *x1 = lower_bound(i_buf + xb[v], i_buf + xe[v], l0);
        int *x2 = upper_bound(i_buf + xb[v], i_buf + xe[v], r0);
        return x2 - x1;
    }
    
    int querya(int l0, int r0, int p, int k) {
        int ans = 0;
        for (int i = k; i <= maxv; i += p)
            ans += querys(i, l0, r0);
        return ans;
    }
    
    int main() {
        freopen("light.in", "r", stdin);
        freopen("light.out", "w", stdout);
    
        scanf("%d%d", &n, &m);
        tib = 0;
        for (int i = 1; i <= n; ++ i)
            scanf("%d", a + i);
        pre();
        while (m --) {
            int l, r, p, k;
            scanf("%d%d%d%d", &l, &r, &p, &k);
            if (p <= bsz)
                printf("%d
    ", queryb(l, r, p, k));
            else
                printf("%d
    ", querya(l, r, p, k));
        }
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    python调用函数
    python递归函数的执行过程
    linux rwx 权限说明
    linux ssh scp免密码
    linux的bash特性
    python3常用的内置函数
    linux清理系统缓存
    vim常用命令
    公司项目安装禅道
    jquery 自定义动画
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7751570.html
Copyright © 2020-2023  润新知