• 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;
    }
    
    
  • 相关阅读:
    关于oracle的导入数据流程,以及错误解决
    解决 lombok 和 freemarker 下载慢问题 以及安装方法
    解决maven项目没有Maven Dependencies
    将maven仓库改为阿里仓库
    Dos攻击和校网渗透
    KaliLinux切换python版本
    Kali国内更新源
    linux安装jdk(.rpm)
    Centos 关于 mysql 命令
    Linux删除命令
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9875301.html
Copyright © 2020-2023  润新知