11525 - Permutation
来源:互联网 发布:无敌淘宝网下载 编辑:程序博客网 时间:2024/06/07 18:07
训练指南P248:不过刚开始这题理解错了,不是找大于val的没有使用过的值,而是找从1开始没有使用过的第val+1个数,并把这个数输出才对//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <stack>#include <queue>#include <cstdio>#include <cstdlib>#include <cmath>#include <set>#include <vector>#include <cstring>#include <algorithm>#define INF 0x3fffffff#define N 50010#define M (50010 << 2)#define LL long long#define mod 95041567using namespace std;struct Node{ int set, sum;};Node p[M];int flag, cnt;void maintain(int rt){ if(p[rt].set) return ; int lc = rt << 1; int rc = lc + 1; p[lc].set = p[rc].set = p[rt].set;}void build(int rt, int l, int r){ p[rt].set = 0; int mid = (r - l) / 2 + l; int lc = rt << 1; int rc = lc + 1; if(l == r){ p[rt].sum = 1; return; } build(lc, l, mid); build(rc, mid + 1, r); p[rt].sum = p[lc].sum + p[rc].sum;}void update(int rt, int l, int r, int val){ // printf(" %d %d %d %d %d\n", l, r, p[rt].sum, p[rt].set, cnt); if(p[rt].set == 1) return; int mid = (r - l) / 2 + l; int lc = rt << 1; int rc = lc + 1; if(l == r){ p[rt].set = 1; p[rt].sum = 0; if(flag) printf(" %d", l); else printf("%d", l), flag = 1; cnt = 1; return; } maintain(rt); if(!cnt && val <= p[lc].sum && p[lc].set != 1) update(lc, l, mid, val); if(!cnt && val - p[lc].sum <= p[rc].sum && p[rc].set != 1) update(rc, mid + 1, r, val - p[lc].sum); if(p[lc].set == p[rc].set && p[lc].set != -1) p[rt].set = p[lc].set; else if(p[lc].set == -1 || p[rc].set == -1) p[rt].set = -1; else if(p[lc].set + p[rc].set == 1) p[rt].set = -1; p[rt].sum = p[lc].sum + p[rc].sum; // printf(" %d %d %d %d %d\n", l, r, p[rt].sum, p[rt].set, cnt);}int main() { // freopen("in.txt", "r", stdin); int t, n, val; scanf("%d", &t); while(t --){ scanf("%d", &n); build(1, 1, n); flag = 0; for(int i = 0; i < n; ++ i){ scanf("%d", &val); // printf("val = %d ", val); cnt = 0; update(1, 1, n, val + 1); // puts(""); } puts(""); } return 0;}