UVALive 6911Double Swords 树状数组

Posted 可是我不配

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive 6911Double Swords 树状数组相关的知识,希望对你有一定的参考价值。

题意:

有n条龙需要杀掉

每条龙需要一把固定攻击力是a的刀和一把攻击力在[b,c]之间的刀

问你最少最少需要多少把刀

 

思路:

训练的时候没有想到用树状数组去查询区间内是否有刀

唉感觉还是太菜了啊 这么简单的方法都没想到

我们先把所有区间按右端点排序

打刀的时候每个区间只要标记右端点就行了

 

  1 #include<bits/stdc++.h>
  2 #define cl(a,b) memset(a,b,sizeof(a))
  3 #define debug(a) cerr<<#a<<"=="<<a<<endl
  4 using namespace std;
  5 typedef long long ll;
  6 typedef pair<int,int> pii;
  7 
  8 const int maxn=1e6+10;
  9 
 10 int tree[maxn<<1];
 11 int vis[maxn<<1];
 12 set<int>st;
 13 
 14 struct point
 15 {
 16     int a;
 17     pii q;
 18     bool operator < (const point& x)const
 19     {
 20         return q<x.q;
 21     }
 22 } pt[maxn];
 23 
 24 void init()
 25 {
 26     st.clear();
 27     cl(pt,0);
 28     cl(tree,0);
 29     cl(vis,0);
 30 }
 31 
 32 int lowbit(int x)
 33 {
 34     return x&(-x);
 35 }
 36 
 37 void add(int x)
 38 {
 39     while(x<maxn)
 40     {
 41         tree[x]++;
 42         x+=lowbit(x);
 43     }
 44 }
 45 
 46 int query(int x)
 47 {
 48     int sum=0;
 49     while(x>0)
 50     {
 51         sum+=tree[x];
 52         x-=lowbit(x);
 53     }
 54     return sum;
 55 }
 56 
 57 int query(int x,int y)
 58 {
 59     return query(y)-query(x-1);
 60 }
 61 
 62 int main()
 63 {
 64     int T,cas=1;
 65     scanf("%d",&T);
 66     init();
 67     while(T--)
 68     {
 69         init();
 70         int n;
 71         scanf("%d",&n);
 72         for(int i=0; i<n; i++)
 73         {
 74             scanf("%d%d%d",&pt[i].a,&pt[i].q.second,&pt[i].q.first);
 75         }
 76         for(int i=0; i<n; i++)
 77         {
 78             if(st.find(pt[i].a)==st.end())
 79             {
 80                 add(pt[i].a);
 81                 st.insert(pt[i].a);
 82             }
 83         }
 84         sort(pt,pt+n);
 85         int ans=st.size();
 86 //        debug(ans);
 87         for(int i=0; i<n; i++)
 88         {
 89             int sum=query(pt[i].q.second,pt[i].q.first);
 90 //            debug(sum);
 91             if(pt[i].a>=pt[i].q.second&&pt[i].a<=pt[i].q.first)
 92             {
 93                 sum--;
 94             }
 95             if(!sum)
 96             {
 97                 add(pt[i].q.first);
 98                 ans++;
 99             }
100         }
101         printf("Case #%d: %d\n",cas++,ans);
102     }
103     return 0;
104 }/*
105 
106 4
107 1
108 7 6 8
109 3
110 3 5 10
111 6 11 15
112 3 13 15
113 4
114 1 10 20
115 3 50 60
116 2 30 40
117 4 70 80
118 2
119 5 100 200
120 150 1000 2000
121 
122 */

 

以上是关于UVALive 6911Double Swords 树状数组的主要内容,如果未能解决你的问题,请参考以下文章

UVALive 6911 Double Swords (Set,贪心,求区间交集)

three swords 9

题解 CF1216D Swords

Codeforces Round #587 (Div. 3) D. Swords

Codeforces Round #587 (Div. 3) D - Swords

Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)