zoukankan      html  css  js  c++  java
  • noip2017列队

    #2319. 「NOIP2017」列队

    链接

    loj

    思路

    动态开点线段树,详见代码。

    代码

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=5e5+7;
    int read() {
    	int x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    int n,m,q,rt[N],ls[N*25],rs[N*25],siz[N*25],tot;
    vector<ll> pos[N];
    int query(int &rt,int l,int r,int k) {
    	if(!rt) rt=++tot,siz[rt]=r-l+1;
    	siz[rt]--;
    	if(l==r) return l;
    	int mid=(l+r)>>1,now=ls[rt]?siz[ls[rt]]:(mid-l+1);
    	if(now>=k) return query(ls[rt],l,mid,k);
    	else return query(rs[rt],mid+1,r,k-now);
    }
    int main() {
    	n=read(),m=read(),q=read();
    	pos[0].push_back(0);
    	for(int i=1;i<=n;++i) pos[0].push_back(pos[0][i-1]+1LL*m);
    	for(int i=1;i<=q;++i) {
    		int x=read(),y=read();
    		int ans=0;
    		if(y==m) ans=pos[0][query(rt[0],1,n+q,x)];
    		else {
    			int id=query(rt[x],1,n+q,y);
    			if(id<m) ans=1LL*(x-1)*m+id;
    			else ans=pos[n][id-m];
    			pos[x].push_back(pos[0][query(rt[0],1,n+q,x)]);
    		}
    		pos[0].push_back(ans);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    思路

    80分暴力,part2莫名挂了5分,初测45

    代码

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #define ls rt<<1
    #define rs rt<<1|1
    #define ll long long
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn = 3e5 + 7;
    int read() {
        int x = 0, f = 1; char s = getchar();
        for (; s < '0' || s > '9'; s = getchar()) if (s == '-') f = -1;
        for (; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
        return x * f;
    }
    int n, m, q;
    int a[1007][1007];
    ll b[maxn];
    inline ll calc(int i, int j) {return (ll)(i - 1) *1LL* m + (ll)j;}
    void part_1() {
        FOR(i, 1, n) FOR(j, 1, m)
        a[i][j] = calc(i, j);
        FOR(kk, 1, q) {
            int x = read(), y = read();
            int ans = a[x][y];
            printf("%d
    ", ans);
            FOR(i, y, m - 1) a[x][i] = a[x][i + 1];
            FOR(i, x, n - 1) a[i][m] = a[i + 1][m];
            a[n][m] = ans;
        }
    }
    vector<ll> h[maxn];
    ll l[maxn];
    void part_2() {
        FOR(i, 1, 300000) h[i].push_back(0);
        FOR(i, 1, n) l[i] = calc(i, m);
        FOR(kk, 1, q) {
            int x = read(), y = read();
            ll ans;
            if (h[x].size() == 1) {
                ans = calc(x, y);
                FOR(i, 1, m) h[x].push_back(calc(x, i));
                h[x][m]=l[m];
            }
            ans = h[x][y];
            FOR(i, y, m - 1) h[x][i] = h[x][i + 1];
            printf("%lld
    ", ans);
            FOR(i, x, n - 1) l[i] = l[i + 1];l[n] = ans;
            h[x][m]=l[x];
        }
    }
    struct edge_node {
        int l, r, size, gs;
        ll su;
    };
    struct seg_tree  {
        edge_node e[maxn *16];
        void pushup(int rt) {
            e[rt].su = e[ls].su + e[rs].su;
            e[rt].gs = e[ls].gs + e[rs].gs;
        }
        void build(int l, int r, int rt) {
            e[rt].l = l, e[rt].r = r, e[rt].size = r - l + 1;
            if (l == r) {
                b[l] ? e[rt].gs = 1, e[rt].su = b[l] : e[rt].gs = e[rt].su = 0;
                return;
            }
            int mid = (l + r) >> 1;
            build(l, mid, ls);
            build(mid + 1, r, rs);
            pushup(rt);
        }
        void delet(int L, int rt) {
            if (e[rt].l == e[rt].r) {
                e[rt].gs = e[rt].su = 0;
                return;
            }
            if (L <= e[ls].gs) delet(L, ls);
            else delet(L - e[ls].gs, rs);
            pushup(rt);
        }
        void add(int L, ll k, int rt) {
            if (e[rt].l == e[rt].r) {
                e[rt].gs = 1, e[rt].su = k;
                return;
            }
            int mid = (e[rt].l + e[rt].r) >> 1;
            if (L <= mid) add(L, k, ls);
            else add(L, k, rs);
            pushup(rt);
        }
        ll query(int L, int rt) {
            if (e[rt].l == e[rt].r)
                return e[rt].su;
            if (L <= e[ls].gs) return query(L, ls);
            else return query(L - e[ls].gs, rs);
        }
    } tree;
    void part_3() {
        FOR(i, 1, m) b[i] = i;
        tree.build(1, m*4, 1);
        int cnt = m;
        FOR(i, 1, q) {
            int x = read(), y = read();
            int ans = tree.query(y, 1);
            printf("%d
    ", ans);
            tree.delet(y, 1);
            tree.add(++cnt, ans, 1);
        }
    }
    queue<ll> qq;
    void part_4()
    {
        FOR(i,1,n) qq.push(calc(i,m));
        FOR(i,1,m) b[i] = i;
        tree.build(1, m*4, 1); 
        int cnt = m;
        FOR(i, 1, q) {
            int x = read(), y = read();
            ll ans = tree.query(y, 1);
            printf("%lld
    ", ans);
            tree.delet(y, 1);
            qq.pop();
            tree.add(++cnt, qq.front(), 1);
            qq.push(ans);
        }
    }
    int main() {
        // freopen("a.out","w",stdout);
        n = read(), m = read(), q = read();
    //	part 1
        if(n<=1000&&m<=1000) {
         	part_1();
         	return 0;
        }
    //	  part 2
        if (q <= 500) {
            part_2();
         	return 0;
        }
    //	 part 3
        if (n == 1) {
         	part_3();
         	return 0;
        }
        part_4();
        return 0;
    }
    
    
  • 相关阅读:
    51nod乘积之和
    Dell服务器安装OpenManage(OMSA)
    Nginx反向代理PHP
    搭建haproxy
    108. Convert Sorted Array to Binary Search Tree
    60. Permutation Sequence
    142. Linked List Cycle II
    129. Sum Root to Leaf Numbers
    118. Pascal's Triangle
    26. Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9875301.html
Copyright © 2011-2022 走看看