zoukankan      html  css  js  c++  java
  • BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化

    我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了

    原来他给的l,r还有k个数字都是下标...

    比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num[r],其中有k个数num[x1],num[x2]....num[xk]这k个数都比l~r区间剩下的(下标不是x1...xk)的任何一个数大。题目就是给m个这种信息然后构造一个符合条件的数列

    知道了这一点可以发现每一个信息都是一组偏序关系,即num[x1] > l~r区间剩下的数 .....num[xk] > l~r区间剩下的数.当然如果数量级小的话直接就每一个关系建一条边直接拓扑排序就可以了.但是这道题数量实在太大,然后这里就有一种黑科技---线段树建图优化.因为我们可以保证每次建边的时候,num[xi]都是和一个区间相连的(单个点也算一个区间),这样我们可考虑区间这个整体,当然具体代码怎么写没这么简单.

    又学到一种黑科技....

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <vector>
      5 #include <queue>
      6 #include <math.h>
      7 #include <string>
      8 #include <algorithm>
      9 #include <time.h>
     10 
     11 #define SIGMA_SIZE 26
     12 #define lson rt<<1
     13 #define rson rt<<1|1
     14 #define lowbit(x) (x&-x)
     15 #define foe(i, a, b) for(int i=a; i<=b; i++)
     16 #define fo(i, a, b) for(int i=a; i<b; i++)
     17 #pragma warning ( disable : 4996 )
     18 
     19 using namespace std;
     20 typedef long long LL;
     21 inline LL LMax(LL a, LL b) { return a>b ? a : b; }
     22 inline LL LMin(LL a, LL b) { return a>b ? b : a; }
     23 inline LL lgcd(LL a, LL b) { return b == 0 ? a : lgcd(b, a%b); }
     24 inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; }  //a*b = gcd*lcm
     25 inline int Max(int a, int b) { return a>b ? a : b; }
     26 inline int Min(int a, int b) { return a>b ? b : a; }
     27 inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
     28 inline int lcm(int a, int b) { return a / gcd(a, b)*b; }  //a*b = gcd*lcm
     29 const LL INF = 0x3f3f3f3f3f3f3f3f;
     30 const LL mod = 1000000007;
     31 const double eps = 1e-8;
     32 const int inf = 0x3f3f3f3f;
     33 const int maxk = 3e6+5;
     34 const int maxn = 1e6+5;
     35 
     36 int cnt, tot;
     37 int indexx[maxn], val1[maxn], val2[maxn], x[maxn], in[maxn];
     38 int linjie[maxn];
     39 int n, s, m;
     40 queue<int> q;
     41 struct node {
     42     int to, nnext, len;
     43 }pp[maxk];
     44 
     45 void addedge( int u, int v, int l )
     46 { pp[cnt].to = v; pp[cnt].len = l; pp[cnt].nnext = linjie[u]; linjie[u] = cnt++; in[v]++; }
     47 
     48 
     49 void build(int rt, int L, int R)
     50 {
     51     if ( L == R )
     52     { indexx[L] = rt; return; }
     53 
     54     int mid = (L+R)>>1;
     55     build(lson, L, mid);
     56     build(rson, mid+1, R);
     57     addedge(lson, rt, 0); addedge(rson, rt, 0);
     58 }
     59 
     60 void update(int rt, int L, int R, int lhs, int rhs, int C)
     61 {
     62     if ( lhs <= L && rhs >= R )
     63     {
     64         addedge(rt, C, 0);
     65         return;
     66     }
     67 
     68     int mid = (L+R)>>1;
     69     if ( lhs <= mid ) update(lson, L, mid, lhs, rhs, C);
     70     if ( rhs >  mid ) update(rson, mid+1, R, lhs, rhs, C);
     71 }
     72 
     73 void init()
     74 {
     75     cnt = 0;
     76     memset(linjie, -1, sizeof(linjie));
     77     build(1, 1, n); tot = n << 2;
     78 
     79     int a, b;
     80     while (s--)
     81     {
     82         scanf("%d %d", &a, &b);
     83         val1[indexx[a]] = val2[indexx[a]] = b;
     84     }
     85 }
     86 
     87 int main()
     88 {
     89     cin >> n >> s >> m;
     90     init();
     91 
     92     int l, r, k;
     93     while (m--)
     94     {
     95         scanf("%d %d %d", &l, &r, &k);
     96         x[0] = l-1; x[k+1] = r+1; tot++;
     97 
     98         foe(i, 1, k) {
     99             scanf("%d", &x[i]);
    100             addedge(tot, indexx[x[i]], 1);
    101         }
    102         
    103         foe(i, 0, k) {
    104             if (x[i+1] - x[i] > 1)
    105                 update(1, 1, n, x[i]+1, x[i+1]-1, tot);
    106         }
    107     }
    108 
    109     foe(i, 1, tot)
    110         if (!in[i]) {
    111             val1[i] = Max(val1[i], 1);
    112             q.push(i);
    113         }
    114     
    115     int a, b;
    116     while (!q.empty())
    117     { 
    118         a = q.front(); q.pop();
    119         for (int i = linjie[a]; ~i; i = pp[i].nnext) {
    120             val1[pp[i].to] = Max(val1[pp[i].to], val1[a]+pp[i].len);
    121             in[pp[i].to] --;
    122 
    123             if (val2[pp[i].to] && val1[pp[i].to] > val2[pp[i].to]) {
    124                 printf("NIE
    ");
    125                 return 0;
    126             }
    127             if ( !in[pp[i].to] )q.push(pp[i].to);
    128         }
    129     }
    130 
    131     foe(i, 1, n)
    132         if ( !val1[indexx[i]] || val1[indexx[i]] > 1000000000)
    133             { printf("NIE
    "); return 0; }
    134 
    135     printf("TAK
    ");
    136     fo(i, 1, n)
    137         printf("%d ", val1[indexx[i]]);
    138     printf("%d
    ", val1[indexx[n]]);
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    网络数据处理
    进程间通信和网络
    附加的操作系统服务
    通用操作系统服务
    UIScrollView 子控件的自动布局经验
    UIImage 添加水印
    数据类型
    ios 获取手机的IP地址
    UILAbel 设置了attributedText 后省略号不显示
    swift
  • 原文地址:https://www.cnblogs.com/chaoswr/p/9385292.html
Copyright © 2011-2022 走看看