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\n",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\n", 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\n", 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\n", 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\n", 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;
}

posted @ 2018-10-30 10:23  ComplexPug  阅读(160)  评论(0编辑  收藏  举报