Yeahpeng's inequality
Time Limit:3000MS Memory Limit:65536K
Total Submit:35 Accepted:5
Description
Yeahpeng is not good at inequality. Unfortunately, there are many inequalities in his homework and they make him be in trouble. Cornered yeah wants your help.
There are n inequalities in total and the form is:
Op x
Op is one of {>=, >, =, <, <=}, x is an integer. What he wants to know is how many inequalities can be satisfied at most in the first i inequalities.
Input
Input contains multiple test cases.
In each test case, the first line is a integer n(1 <= n <= 50,000)
The following n line is the inequalities [op x].
Output
For each test case print n lines. An integer in each line, the maximum numbers can be satisfied in the first i inequalities.
Sample Input
5
<= 10
< 9
> 6
>= 7
= 8
Sample Output
1
2
3
4
5
题意:给定n个不等式,第i次询问前i个不等式中可以有几个共存。
思路:每个不等式对应了一个区间,即询问区间上被覆盖次数最多的点被覆盖了几次。
解法:先将所有的不等式读入,然后将x离散化一下,把>,<强制转化为>=,<=,然后把区间放到线段树上,每次更新一个区间,树根的max值即为整段区间上被覆盖次数最多的点的覆盖次数。因为每次都要覆盖,可以打一下lazy标记。
AC代码:
//************************************************************************// //*Author : Handsome How *// //************************************************************************// //#pragma comment(linker, "/STA CK:1024000000,1024000000") #include <vector> #include <map> #include <set> #include <queue> #include <stack> #include <algorithm> #include <sstream> #include <iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #include <ctime> using namespace std; typedef long long ll; //---------------------------------------------------------- /* 将不等式的x离散化一下,对于每一个出现的数,映射为2*他的排名 即i=rank[i]*2 那么 >=x 覆盖的区间为[2*rank[x],maxlen] >x 覆盖的区间为[2*rank[x]+1,maxlen] <=x 覆盖的区间为[0,2*rank[x]] <x 覆盖的区间为[0,2*rank[x]-1] 建立线段树维护区间内覆盖点的次数 那么根结点的max值即为所有区间内被覆盖最多点的次数 */ const int maxn = 50000+5; int n,maxlen; map<ll,int>rk; struct Node{ ll v; char op[5]; }node[maxn+5],ori[maxn+5];//分别记录排序后的以及原来的不等式 struct Tree{ int l; int r; int max; int lazy; }tree[maxn*4*4+5]; void build(int l,int r,int root){ tree[root].l = l;tree[root].r=r; tree[root].max = 0; tree[root].lazy = 0; if(l==r) return; int mid = (l+r)>>1; build(l,mid,root<<1); build(mid+1,r,root<<1|1); } bool cmp(Node a,Node b){return a.v<b.v;} void pushdown(int root){ int lazy = tree[root].lazy ; tree[root].lazy = 0; tree[root<<1].max +=lazy; tree[root<<1].lazy +=lazy; tree[root<<1|1].max +=lazy; tree[root<<1|1].lazy +=lazy; } void init(){ rk.clear(); int count = 1; sort(node+1,node+1+n,cmp); for(int i=1;i<=n;i++){ if(rk[node[i].v]==0){ //离散化 将 >=a 的标记为偶数2n 这样如果>a 可强制转化为>=2n+1 rk[node[i].v]=count*2; //将<a 强制转化为<=2n-a count++; } } maxlen=count*2+2; build(1,maxlen,1); } void cover(int l,int r,int root){ if(tree[root].l==tree[root].r){ if(tree[root].l>=l&&tree[root].l<=r) //找到最后单点的叶子 判断是否被区间覆盖 tree[root].max++; return; } if(l>tree[root].r||r<tree[root].l)return; //超出范围 不能覆盖 if(tree[root].l>=l&&tree[root].r<=r){ //打lazy标记 tree[root].max++; tree[root].lazy++; return; } pushdown(root); cover(l,r,root<<1); cover(l,r,root<<1|1); tree[root].max = max(tree[root<<1].max ,tree[root<<1|1].max); } int main() { while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++){ scanf("%s",node[i].op); strcpy(ori[i].op,node[i].op); scanf("%d",&node[i].v); ori[i].v=node[i].v; //读入不等式并拷贝一份 } init(); for(int i=1;i<=n;i++){ if(ori[i].op[0]=='=') cover(rk[ori[i].v],rk[ori[i].v],1); else if(ori[i].op[0]=='>'&&ori[i].op[1]=='=') cover(rk[ori[i].v],maxlen,1); else if(ori[i].op[0]=='<'&&ori[i].op[1]=='=') cover(0,rk[ori[i].v],1); else if(ori[i].op[0]=='>') cover(rk[ori[i].v]+1,maxlen,1); else cover(0,rk[ori[i].v]-1,1); printf("%d\n",tree[1].max); } } return 0; }