zoukankan      html  css  js  c++  java
  • 线段树·二

    1、UVA 11525 Permutation

      题意:求1~k这k个数中第N个排列。(N从0开始记)。N=sum(Si*(k-i)!)(1≤i≤k)

      思路:根据N的值的性质,联系康拓展开,不妨发现第i位的值为剩下没用的数中从小到大第Si+1个。可以用线段树来记录区间内没有用的数的个数。

     1 #include<iostream>
     2 using namespace std;
     3 int k;
     4 const int maxk = 50010;
     5 int numk[maxk];
     6 int tree[maxk << 2];
     7 void Build(int root, int l, int r)
     8 {
     9     if (l == r)
    10     {
    11         tree[root] = 1;
    12         return;
    13     }
    14     int mid = (l + r) / 2;
    15     Build(root * 2, l, mid);
    16     Build(root * 2 + 1, mid + 1, r);
    17     tree[root] = tree[root * 2] + tree[root * 2 + 1];
    18 }
    19 int pos;
    20 void Query(int root, int l, int r, int x)
    21 {
    22     if (l == r)
    23     {
    24         tree[root] = 0;
    25         pos = l;
    26         return;
    27     }
    28     int mid = (l + r) / 2;
    29     if (x <= tree[root*2]) Query(root * 2, l, mid, x);
    30     else Query(root * 2 + 1, mid + 1, r, x - tree[root * 2]);
    31     tree[root] = tree[root * 2] + tree[root * 2 + 1];
    32 }
    33 int main()
    34 {
    35     int t;
    36     scanf("%d", &t);
    37     while (t--)
    38     {
    39         scanf("%d", &k);
    40         Build(1, 1, k);
    41         for (int i = 1; i <= k; i++)
    42         {
    43             int num;
    44             scanf("%d", &num);
    45             if (i > 1) printf(" ");
    46             pos = 0;
    47             Query(1, 1, k, num + 1);
    48             printf("%d", pos);
    49         }
    50         printf("
    ");
    51     }
    52     return 0;
    53 }
    View Code

     2、LA 4730 Kingdom

      题意:每次可以连接两个城市,或询问纵坐标为y的直线所穿过的城市群及其总的城市数目。

      思路:用并查集维护每个城市群的最大y值、最小y值、城市数;由于询问的纵坐标的值始终小数部分为0.5,那么我们把每个城市群的最小y值+1,所询问纵坐标向上取整。

      1 #include<iostream>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn = 100100;//最多城市数
      7 const int maxy = 1000100;//y坐标最大值
      8 struct node
      9 {
     10     int states;
     11     int citys;
     12     int addst;
     13     int addct;
     14 }tree[maxy<<2];
     15 
     16 int vy[maxn];//存每个城市的y坐标
     17 int pre[maxn];//存祖先
     18 int maxh[maxn];//存连通块的最大y值
     19 int minh[maxn];//存连通块的最小y值
     20 int cnt[maxn];//存连通块的城市数目
     21 int Find(int x)
     22 {
     23     if (x == pre[x]) return x;
     24     else
     25     {
     26         int fa = pre[x];
     27         pre[x] = Find(fa);
     28         return pre[x];
     29     }
     30 }
     31 void PushDown(int root, int l, int r)
     32 {
     33     if (tree[root].addct!=0)
     34     {
     35         tree[root * 2].citys += tree[root].addct;
     36         tree[root * 2+1].citys += tree[root].addct;
     37         tree[root * 2].addct += tree[root].addct;
     38         tree[root * 2 + 1].addct += tree[root].addct;
     39         tree[root].addct = 0;
     40     }
     41     if (tree[root].addst!=0)
     42     {
     43         tree[root * 2].states += tree[root].addst;
     44         tree[root * 2 + 1].states += tree[root].addst;
     45         tree[root * 2].addst += tree[root].addst;
     46         tree[root * 2 + 1].addst += tree[root].addst;
     47         tree[root].addst = 0;
     48     }
     49 }
     50 void Build(int root, int l, int r)
     51 {
     52     tree[root].citys = tree[root].states = tree[root].addct = tree[root].addst = 0;
     53     if(l==r)return;
     54     int mid = (l + r) / 2;
     55     Build(root * 2, l, mid);
     56     Build(root * 2 + 1, mid + 1, r);
     57 }
     58 void Update(int root, int l, int r, int ul, int ur, int v, int flag)
     59 {//flag=1,addcity;flag=2,addstate
     60     if (l > ur || r < ul) return;
     61     if (l >= ul&&r <= ur)
     62     {
     63         if (flag == 1)
     64         {
     65             tree[root].citys += v;
     66             tree[root].addct += v;
     67         }
     68         else
     69         {
     70             tree[root].states += v;
     71             tree[root].addst += v;
     72         }
     73         return;
     74     }
     75     PushDown(root, l, r);
     76     int mid = (l + r) / 2;
     77     Update(root * 2, l, mid, ul, ur, v, flag);
     78     Update(root * 2 + 1, mid + 1, r, ul, ur, v, flag);
     79 }
     80 pair<int, int> Query(int root, int l, int r, int posy)
     81 {
     82     //if (l > posy || r < posy) return make_pair(0, 0);
     83     if (l == r&&l == posy)
     84     {
     85         return make_pair(tree[root].states, tree[root].citys);
     86     }
     87     PushDown(root, l, r);
     88     int mid = (l + r) / 2;
     89     if (posy <= mid) return Query(root * 2, l, mid, posy);
     90     else return Query(root * 2 + 1, mid + 1, r, posy);
     91 }
     92 void Union(int u, int v)
     93 {
     94     int fu = Find(u), fv = Find(v);
     95     if (fu != fv)
     96     {
     97         if (minh[fu] < maxh[fu])
     98         {
     99             Update(1, 0, maxy - 1, minh[fu] + 1, maxh[fu], -cnt[fu], 1);
    100             Update(1, 0, maxy - 1, minh[fu] + 1, maxh[fu], -1, 2);
    101         }
    102         if (minh[fv] < maxh[fv])
    103         {
    104             Update(1, 0, maxy - 1, minh[fv] + 1, maxh[fv], -cnt[fv], 1);
    105             Update(1, 0, maxy - 1, minh[fv] + 1, maxh[fv], -1, 2);
    106         }
    107         if (fu > fv) swap(fu, fv);//约定以小的为祖先
    108         pre[fv] = fu;
    109         minh[fu] = min(minh[fu], minh[fv]);
    110         maxh[fu] = max(maxh[fu], maxh[fv]);
    111         cnt[fu] += cnt[fv];
    112         Update(1, 0, maxy - 1, minh[fu] + 1, maxh[fu], cnt[fu], 1);
    113         Update(1, 0, maxy - 1, minh[fu] + 1, maxh[fu],1, 2);
    114     }
    115 }
    116 void Solve()
    117 {
    118     int n;
    119     scanf("%d", &n);
    120     int x;
    121     for (int i = 0; i < n; i++) scanf("%d%d", &x, &vy[i]);
    122     Build(1, 0, maxy - 1);
    123     for (int i = 0; i < n; i++) pre[i] = i, maxh[i] = vy[i], minh[i] = vy[i], cnt[i] = 1;
    124     int q;
    125     scanf("%d", &q);
    126     char s[10];
    127     while (q--)
    128     {
    129         scanf("%s", s);
    130         if (s[0] == 'r')
    131         {
    132             int u, v;
    133             scanf("%d%d", &u, &v);
    134             Union(u, v);
    135         }
    136         else
    137         {
    138             double posy;
    139             scanf("%lf", &posy);
    140             pair<int, int>ans = Query(1, 0, maxy - 1,int(posy+1));
    141             printf("%d %d
    ", ans.first, ans.second);
    142         }
    143     }
    144 }
    145 int main()
    146 {
    147     int t;
    148     scanf("%d", &t);
    149     while (t--)
    150     {
    151         Solve();
    152     }
    153     return 0;
    154 }
    View Code

     3、LA 5694/UVA 1492/hdu 4052 Adding New Machine

      题意:w*h大小的房间一些矩形区域已经有物品,现在要放一个1*m大小的物品,问有多少种放法。

      思路:分横着和竖着考虑。以横着为例,每个矩形区域右侧m-1区域放不了,以及0~m-1位置放不了。用总面积减去这样所有的矩形面积并则是横着的方案数。竖着类似。注意n==0和m==1的情况。

      1 #include <iostream>
      2 #include <vector>
      3 #include <cmath>
      4 #include <map>
      5 #include <cstdio>
      6 #include <algorithm>
      7 using namespace std;
      8 
      9 typedef long long ll;
     10 
     11 const int maxn = 51000;
     12 struct node
     13 {
     14     int l, r, pos, c;
     15     node(int l0 = 0, int r0 = 0, int pos0 = 0, int c0 = 0)
     16     {
     17         l = l0, r = r0, pos = pos0; c = c0;
     18     }
     19     friend bool operator < (node a, node b)
     20     {
     21         return a.pos<b.pos;
     22     }
     23 };
     24 
     25 struct rec
     26 {
     27     int x1, y1, x2, y2;
     28 }d[maxn];
     29 
     30 
     31 vector <node> v;
     32 int w, h, m, n;
     33 vector <int> c;
     34 map <int, int> mp;
     35 
     36 struct Tree
     37 {
     38     int l, r, cover, len;
     39 }tree[8 * maxn];
     40 
     41 void build(int l, int r, int k)
     42 {
     43     tree[k].l = l;
     44     tree[k].r = r;
     45     tree[k].len = 0;
     46     tree[k].cover = 0;
     47     if (l + 1 >= r) return;
     48     int mid = (l + r) >> 1;
     49     build(l, mid, k << 1);
     50     build(mid, r, k << 1 | 1);
     51 }
     52 
     53 void pushup(int root)
     54 {
     55     if (tree[root].cover>0) tree[root].len = c[tree[root].r] - c[tree[root].l];
     56     else if (tree[root].l + 1 == tree[root].r) tree[root].len = 0;
     57     else tree[root].len = tree[root << 1].len + tree[root << 1 | 1].len;
     58 }
     59 
     60 void insert(int l, int r, int root, int c0)
     61 {
     62     if (l <= tree[root].l && tree[root].r <= r)
     63     {
     64         tree[root].cover += c0;
     65     }
     66     else
     67     {
     68         int mid = (tree[root].l + tree[root].r) >> 1;
     69         if (r <= mid) insert(l, r, root << 1, c0);
     70         else if (l >= mid) insert(l, r, root << 1 | 1, c0);
     71         else
     72         {
     73             insert(l, mid, root << 1, c0);
     74             insert(mid, r, root << 1 | 1, c0);
     75         }
     76     }
     77     pushup(root);
     78 }
     79 
     80 ll getans()
     81 {
     82     if (v.size() <= 0) return (ll)w*(ll)h;
     83     c.clear();
     84     mp.clear();
     85     sort(v.begin(), v.end());
     86     for (int i = 0; i<v.size(); i++)
     87     {
     88         mp[v[i].l] = i;
     89         mp[v[i].r] = i;
     90     }
     91     for (map <int, int>::iterator it = mp.begin(); it != mp.end(); it++)
     92     {
     93         it->second = c.size();
     94         c.push_back(it->first);
     95     }
     96     ll ret = 0;
     97     build(0, c.size() - 1, 1);
     98     insert(mp[v[0].l], mp[v[0].r], 1, v[0].c);
     99     for (int i = 1; i<v.size(); i++)
    100     {
    101         ret += (ll)(v[i].pos - v[i - 1].pos)*(ll)tree[1].len;
    102         insert(mp[v[i].l], mp[v[i].r], 1, v[i].c);
    103     }
    104     return (ll)w*(ll)h - ret;
    105 }
    106 
    107 void solve()
    108 {
    109     v.clear();
    110     for (int i = 0; i<n; i++)
    111     {
    112         v.push_back(node(max(d[i].x1 + 1 - m, 0), d[i].x2, d[i].y1, 1));
    113         v.push_back(node(max(d[i].x1 + 1 - m, 0), d[i].x2, d[i].y2, -1));
    114     }
    115     if (m>1)
    116     {
    117         v.push_back(node(max(0, w + 1 - m), w, 0, 1));
    118         v.push_back(node(max(0, w + 1 - m), w, h, -1));
    119     }
    120 
    121     ll ans = getans();
    122 
    123     if (m == 1)
    124     {
    125         printf("%lld
    ", ans);
    126         return;
    127     }
    128 
    129     v.clear();
    130     for (int i = 0; i<n; i++)
    131     {
    132         v.push_back(node(max(d[i].y1 + 1 - m, 0), d[i].y2, d[i].x1, 1));
    133         v.push_back(node(max(d[i].y1 + 1 - m, 0), d[i].y2, d[i].x2, -1));
    134     }
    135     if (m>1)
    136     {
    137         v.push_back(node(max(0, h + 1 - m), h, 0, 1));
    138         v.push_back(node(max(0, h + 1 - m), h, w, -1));
    139     }
    140     ans += getans();
    141     printf("%lld
    ", ans);
    142 }
    143 
    144 int main()
    145 {
    146     while (scanf("%d%d%d%d", &w, &h, &n, &m) != EOF)
    147     {
    148         for (int i = 0; i<n; i++)
    149         {
    150             scanf("%d%d%d%d", &d[i].x1, &d[i].y1, &d[i].x2, &d[i].y2);
    151             d[i].x1--; d[i].y1--;
    152         }
    153         solve();
    154     }
    155     return 0;
    156 }
    View Code
  • 相关阅读:
    记一个诡异的.net framework问题造成的系统问题(visual studio不能build或不能正常运行代码,所有基于.net framework的代码无法运行)
    Dependency Walker工具:定位DLL缺失位置
    (转)MVC4.0教程
    剑灵-控制技能图及武器升级图
    (转)哑铃健身图解大全
    Python-第三方库requests详解
    Mac更改PHP默认目录的方法
    MySQL语句之数据的增删改查
    mysql语句之DDL
    linux下查看某个文件位置的方法
  • 原文地址:https://www.cnblogs.com/ivan-count/p/7465904.html
Copyright © 2011-2022 走看看