• 2019 ICPC 南京网络赛


    A. 00:40:35 solved by hl

    很显然需要一种方法O(1)定位x,y上的数字,利用矩阵的规律可以找到

    然后就是一个子矩阵和问题,小范围可以直接二维前缀和,大范围就是一个二位偏序问题,

    将一个询问拆成4个询问,树状数组解决即可

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <bitset>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x)  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x)  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int 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 x*f;}
    const double PI = acos(-1.0);
    const double eps = 1e-9;
    const int maxn = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,Q;
    LL pre[maxn];
    void init(){
        pre[0] = 0;
        for(int sum = N,i = 1; sum > 0; i ++,sum -= 2){
            pre[i] = pre[i - 1] + sum + sum + sum + sum - 4;
        }
    }
    inline int min(int a,int b,int c,int d){
        return min(min(min(a,b),c),d);
    }
    inline LL id(int x,int y){
        int q = min(x,y,N - x + 1,N - y + 1);
        LL ans = pre[q - 1] + 1;
        int sx = N - q + 1,sy = N - q + 1;
        if(sx == x) return ans + sy - y;
        ans += sy - q; sy = q;
        if(sy == y) return ans + sx - x;
        ans += sx - q; sx = q;
        if(sx == x) return ans + y - sy;
        ans += (N - q + 1) - sy; sy = N - q + 1;
        return ans + x - sx;
    }
    inline LL val(int x,int y){
        LL sum = id(x,y);
        LL ans = 0;
        while(sum){
            ans += sum % 10;
            sum /= 10;
        }
        return ans;
    }
    struct Good{
        int x,y;
        LL ans;
    }g[maxn];
    struct Query{
        int x,y,id,flag;
        Query(int x = 0,int y = 0,int id = 0,int flag = 0):x(x),y(y),id(id),flag(flag){}
    }query[maxn];
    LL fans[maxn];
    bool cmp(Good a,Good b){
        return a.x < b.x;
    }
    LL tree[maxn];
    void add(int u,int v){
        for(;u <= N; u += u & -u) tree[u] += v;
    }
    LL getsum(int u){
        LL ans = 0;
        for(;u > 0; u -= u & -u) ans += tree[u];
        return ans;
    }
    bool cmp2(Query a,Query b){
        return a.x < b.x;
    }
    int main(){
        int T = read();
        while(T--){
            Mem(tree,0);
            Sca3(N,M,Q);init();
            for(int i = 1; i <= Q; i ++) fans[i] = 0;
            for(int i = 1; i <= M; i ++){
                g[i].x = read(),g[i].y = read();
                g[i].ans = val(g[i].x,g[i].y);
            }
            int cnt = 0;
            for(int i = 1; i <= Q; i ++){
                int x1 = read(),y1 = read(),x2 = read(),y2 = read();
                query[++cnt] = Query(x1 - 1,y1 - 1,i,1);
                query[++cnt] = Query(x2,y1 - 1,i,-1);
                query[++cnt] = Query(x1 - 1,y2,i,-1);
                query[++cnt] = Query(x2,y2,i,1);
            }
            sort(g + 1,g + 1 + M,cmp);
            sort(query + 1,query + 1 + cnt,cmp2);
            int s1 = 1,s2 = 1;
            for(int i = 0; i <= N ; i ++){
                while(s1 <= M && g[s1].x == i){
                    add(g[s1].y,g[s1].ans);
                    s1++;
                }
                while(s2 <= cnt && query[s2].x == i){
                    fans[query[s2].id] += query[s2].flag * getsum(query[s2].y);
                    s2++;
                }
            }
            for(int i = 1; i <= Q; i ++) Prl(fans[i]);
        }
    
        
        return 0;
    }
    A

    B.1:42:29(-1) solved by gbs

    队友说 是裸的指数循环节

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <map>
    #include <set>
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    
    using namespace std;
    
    typedef long long LL;
    
    int a,b,m;
    LL eular(LL n)
    {
        LL ans = n;
        for (int i = 2; i * i <= n; i++)
        {
            if (n % i == 0)
            {
                ans -= ans / i;
                while (n % i == 0)
                    n /= i;
            }
        }
        if (n != 1)
            ans -=ans / n;
        return ans;
    }
    const LL mod = 1e9 + 7; //¿ìËÙÃÝ
    int quick_mi(LL a, LL k,LL mod)
    {
        if (k == 0)
            return 1;
        if (a<=1)
            return a;
        bool if_over = false;
        LL k1 = 1;
        for (int i=0; i<k; i++)
        {
            k1 = k1*a;
            if (k1>= mod)
            {
                if_over = true;
                break;
            }
        }
        LL ans = 1;
        while (k)
        {
            if (k & 1)
            {
                ans *= a;
                ans %= mod;
            }
            a *= a;
            a %= mod;
            k >>= 1;
        }
        if (if_over)
        {
            ans += mod;
        }
        return ans;
    }
    
    LL dfs(int a,int b,LL mod)
    {
        if (b == 0)
            return 1;
        if (b == 1)
            return a;
        if (mod == 1)
            return 1;
        LL h1=quick_mi(a,dfs(a,b-1,eular(mod)),mod);
        //cout<<mod<<' '<<h1<<endl;
        return h1;
    }
    
    int main()
    {
        int t;
        
        cin >>t;
        while(t--)
        {
            cin >>a>>b>>m;
            int h1 = dfs(a,b,m);
            cout<<h1%m<<endl;;
        }
    
    
    
    
    #ifdef VSCode
        system("pause");
    #endif
        return 0;
    }
    B

    D.00:44:59 solved by zcz

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    
    double p1[100005],p2[100005];
    int n,m;
    vector<int> e[100005];
    
    double getp2(int u)
    {
        if(p2[u]>=0)    return p2[u];
        int l=e[u].size();
        double rec=0;
        for(int i=0;i<l;i++)
        {
            rec+=getp2(e[u][i])+1;
        }
        p2[u]=(rec+1)/l;
        return p2[u];
    }
    
    double getp1(int u)
    {
        if(p1[u]>=0)    return p1[u];
        int l=e[u].size();
        double rec=0;
        for(int i=0;i<l;i++)
        {
            rec+=getp1(e[u][i])+p2[e[u][i]];
        }
        p1[u]=(rec+p2[u])/l;
        return p1[u];
    }
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            cin>>n>>m;
            for(int i=1;i<=n;i++)
            {
                p1[i]=-1,p2[i]=-1;
                e[i].clear();
            }
            p2[n]=1;
            p1[n]=0;
            while(m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                e[u].push_back(v);
            }
            getp2(1);
            getp1(1);
            printf("%.2lf
    ",p1[1]);
        }
    
    
        return 0;
    }
    D

    F. 1:30:28 solved by zcz and hl

    线段树维护区间最大值的下标,按照数的大小从小到大询问然后修改

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <bitset>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x)  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x)  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int 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 x*f;}
    const double PI = acos(-1.0);
    const double eps = 1e-9;
    const int maxn = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int a[maxn],id[maxn];
    int ans[maxn];
    struct node{
        int pos,val;
        node(int pos = 0,int val = 0):pos(pos),val(val){}
        friend node operator + (node a,node b){
            if(a.val < b.val) return b;
            return a;
        }
    };
    struct Tree{
        int l,r;
        node ans;
    }tree[maxn << 2];
    void Pushup(int t){
        tree[t].ans = tree[t << 1].ans + tree[t << 1 | 1].ans;
    }
    void Build(int t,int l,int r){
        tree[t].l = l ; tree[t].r = r;
        tree[t].ans = node(0,0);
        if(l == r){
            tree[t].ans = node(l,0);
            return;
        }
        int m = l + r >> 1;
        Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
        Pushup(t);
    }
    node query(int t,int l,int r){
        if(l <= tree[t].l && tree[t].r <= r){
            return tree[t].ans;
        }
        int m = tree[t].l + tree[t].r >> 1;
        if(r <= m) return query(t << 1,l,r);
        else if(l > m) return query(t << 1 | 1,l,r);
        else{
            return query(t << 1,l,m) + query(t << 1 | 1,m + 1,r);
        }
    }
    void update(int t,int pos){
        if(tree[t].l == tree[t].r){
            tree[t].ans.val = a[pos];
            return; 
        }
        int m = (tree[t].l + tree[t].r) >> 1;
        if(pos <= m)  update(t << 1,pos);
        else update(t << 1 | 1,pos);
        Pushup(t);
    }
    int main(){
        int T = read();
        while(T--){
            Sca2(N,K);
            for(int i = 1; i <= N; i ++) ans[i] = 0;
            for(int i = 1; i <= N ; i ++) Sca(a[i]),id[a[i]] = i;
            Build(1,1,N);
            for(int i = 1; i <= N ; i ++){
                int l = max(1,id[i] - K),r = min(N,id[i] + K);
                node t = query(1,l,r);
                ans[i] = ans[t.val] + 1;
                update(1,id[i]);
            }
            for(int i = 1; i <= N; i ++){
                printf("%d",ans[i]);
                if(i != N) printf(" ");
            }
            puts("");
        }
        return 0;
    }
    F

    G.4:35:30(-7) solved by zcz

    一个很麻烦的线性规划

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    long long f(long long a,long long b,long long c)
    {
        if(a<b)
        {
            long long t=a;
            a=b;
            b=t;
        }
        if(c<0) return 0;
        if(c>=a+b)  return (a+1)*(b+1);
        if(c<=b)    return (c+1)*(c+2)/2;
        if(b<c&&c<a)    return (b+1)*(b+2)/2+(c-b)*(b+1);
        long long t=a+b-c;
        return (a+1)*(b+1)- t*(t+1)/2;
    }
    
    long long f2(long long x)
    {
        return (3*x*(x+1)+x*(x+1)*(2*x+1))/12;
    }
    
    long long f3(long long x)
    {
        return x*(x+1)/2;
    }
    
    long long f4(long long a,long long b,long long c)
    {
        if(a<b)
        {
            long long t=a;
            a=b;
            b=t;
        }
        if(c<0) return 0;
        if(c<=b)    return f2(c+1);
        if(c<=a)    return f2(b+1)+f3(b+1)*(c-b)+f3(c-b)*(b+1);
        long long tem=f4(a,b,a);
        if(c<=a+b)  return tem+f(a,b,a)*(c-a)+b*f3(c-a)-f2(c-a-1);
        return f4(a,b,a+b)+f(a,b,a+b)*(c-(a+b));
    }
    
    int main()
    {
        //cout<<f(2,2,2)<<endl;
        //cout<<f4(3,3,6);
        int T;
        cin>>T;
        while(T--)
        {
            long long l1,l2,l3,l4,r1,r2,r3,r4;
            cin>>l1>>r1>>l2>>r2>>l3>>r3>>l4>>r4;
            if(r1<l1||r2<l2||r3<l3||r4<l4)
            {
                cout<<0<<endl;
                continue;
            }
            long long ans=0;
            for(long long d=l4;d<=r4;d++)
            {
                ans+=f4(r1-l1,r2-l2,r3-d-l1-l2)-f4(r1-l1,r2-l2,l3-d-l1-l2-1);
                ans+=f4(r2-l2,r3-l3,r1-d-l2-l3)-f4(r2-l2,r3-l3,l1-d-l2-l3-1);
                ans+=f4(r1-l1,r3-l3,r2-d-l1-l3)-f4(r1-l1,r3-l3,l2-d-l1-l3-1);
                ans+=f4(r1-l1,r2-l2,d-l1-l2-l3)-f4(r1-l1,r2-l2,d-l1-l2-r3-1);
            }
            ans=(r1-l1+1)*(r2-l2+1)*(r3-l3+1)*(r4-l4+1)-ans;
            cout<<ans<<endl;
        }
    /*
    666
    1 2 1 2 1 2 1 888
    1 888 1 2 1 2 1 2
    */
    
    
        return 0;
    }
    G

    H.1:06:48(-1) solved by hl

    没有负环的条件是没有一条来的路和加的边加起来为负,所以每次加的边为反向最短路

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <bitset>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x)  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x)  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int 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 x*f;}
    const double PI = acos(-1.0);
    const double eps = 1e-9;
    const int maxn = 310;
    const int maxm = 710;
    const LL INF = 1e18;
    const int mod = 1e9 + 7; 
    int N,M,K;
    struct Edge{
        int to,next;
        LL dis;
    }edge[maxm * 2];
    int head[maxn],tot;
    void init(){
        for(int i = 0 ; i <= N ; i ++) head[i] = -1;
        tot = 0;
    }
    void add(int u,int v,LL w){
        edge[tot].to = v;
        edge[tot].next = head[u];
        edge[tot].dis = w;
        head[u] = tot++;
    }
    LL dis[1005],vis[1005];
    struct node{
        int pos;
        LL val;
        node(int pos,LL val):pos(pos),val(val){}
        friend bool operator < (node a,node b){
            return a.val > b.val;
        }
    };
    LL Dijkstra(int s,int t){
        for(int i = 0; i <= N ; i ++) dis[i] = INF;
        dis[s] = 0;
        priority_queue<node>Q;
        Q.push(node(s,0));
        while(!Q.empty()){
            node u = Q.top(); Q.pop();
            if(u.val > dis[u.pos]) continue;
            for(int i = head[u.pos]; ~i; i = edge[i].next){
                int v = edge[i].to;
                if(dis[v] > edge[i].dis + u.val){
                    dis[v] = edge[i].dis + u.val;
                    Q.push(node(v,dis[v]));
                }
            }
        }
        return dis[t];
    }
    int main(){
        int T = read();
        while(T--){
            Sca2(N,M); init();
            for(int i = 1; i <= M ; i ++){
                int u = read(),v = read(); LL w = read();
                add(u,v,w);
            }
            for(int i = 1; i <= 6; i ++){
                int u = read(),v = read();
                //S = u,T = v;
                LL ans = -Dijkstra(v,u);
                add(u,v,ans);
                Prl(ans);
            }
        }
        return 0;
    }
    H

    I.2:40:04(-5) solved by gbs

    已经多次证实两个人敲同一道题的后果就是罚时++

    hl赛后补题 

    隐约听到了队友说的类似于玄学,暴力之类的做法

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <map>
    #include <set>
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    
    using namespace std;
    
    typedef long long LL;
    
    int an[1123456];
    int ans[123456];
    
    int main()
    {
        int N;
        int y;
        while(cin >>N>>y)
        {
            for (int i=0; i<N; i++)
            {
                scanf("%d",&an[i]);
            }
            if (N ==1)
            {
                for (int j=1 ;j<=y; j++)
                {
                    ans[j] = an[0] + j;
                }
            }
            else
            {
                sort(an,an+N);
                int nowi = N-1;
                int now_ans ;
                for (int j=y; j>=1; j--)
                {
                    if (nowi == 0)
                    {
                        ans[j] = an[N-1]+j;
                        continue;
                    }
                    now_ans = max(an[N-1]+j,an[nowi-1]+y);
                    while(an[nowi-1] + j<=an[nowi])
                    {
                        nowi--;
                        if (nowi == 0)
                        {
                            now_ans = an[N-1]+j;
                            break;
                        }  
                        now_ans = max(an[N-1]+j,an[nowi-1]+y);
                    }
                    ans[j] = now_ans;
                }
            }
            for (int j=1; j<=y; j++)
            {
                if (j!=1)
                    printf(" ");
                printf("%d",ans[j]);
            }
            printf("
    ");
            
        }
    
    
    
    
    #ifdef VSCode
        system("pause");
    #endif
        return 0;
    }
    I
  • 相关阅读:
    MyBatis入门
    Java JDBC
    Spring MVC
    Java内存模型
    Java日志
    Java I/O模型
    Java异常处理
    Java泛型设计
    Java反射
    Java代理
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/11443296.html
Copyright © 2020-2023  润新知