CodeForces - 283E Cow Tennis Tournament
Discription
Farmer John is hosting a tennis tournament with his n cows. Each cow has a skill level si, and no two cows having the same skill level. Every cow plays every other cow exactly once in the tournament, and each cow beats every cow with skill level lower than its own.
However, Farmer John thinks the tournament will be demoralizing for the weakest cows who lose most or all of their matches, so he wants to flip some of the results. In particular, at k different instances, he will take two integers ai, bi (ai < bi) and flip all the results between cows with skill level between ai and bi inclusive. That is, for any pair x, y he will change the result of the match on the final scoreboard (so if x won the match, the scoreboard will now display that ywon the match, and vice versa). It is possible that Farmer John will change the result of a match multiple times. It is not guaranteed that ai and bi are equal to some cow's skill level.
Farmer John wants to determine how balanced he made the tournament results look. In particular, he wants to count the number of triples of cows (p, q, r) for which the final leaderboard shows that cow p beats cow q, cow q beats cow r, and cow r beats cow p. Help him determine this number.
Note that two triples are considered different if they do not contain the same set of cows (i.e. if there is a cow in one triple that is not in the other).
Input
On the first line are two space-separated integers, n and k (3 ≤ n ≤ 105; 0 ≤ k ≤ 105). On the next line are n space-separated distinct integers, s1, s2, ..., sn (1 ≤ si ≤ 109), denoting the skill levels of the cows. On the next k lines are two space separated integers, ai and bi (1 ≤ ai < bi ≤ 109) representing the changes Farmer John made to the scoreboard in the order he makes it.
Output
A single integer, containing the number of triples of cows (p, q, r) for which the final leaderboard shows that cow p beats cow q, cow q beats cow r, and cow r beats cow p.
Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Examples
3 2
1 2 3
1 2
2 3
1
5 3
5 9 4 1 7
1 7
2 8
3 9
3
Note
In the first sample, cow 3 > cow 1, cow 3 > cow 2, and cow 2 > cow 1. However, the results between cows 1 and 2 and cows 2 and 3 are flipped, so now FJ's results show that cow 1 > cow 2, cow 2 > cow 3, and cow 3 > cow 1, so cows 1, 2, and 3 form a balanced triple.
jzh大佬给学弟学妹们讲课的课件里,唯一一个不是弱智题的就是这个了2333,然鹅一找原题,mdzz数据范围后面加了俩0,有毒。。。
如果n<=1000的话,我们可以很容易的用差分去维护区间覆盖的问题,然后暴力计算每两个牛之间的比赛结果就好了。。。
所以n<=1e5怎么做呢??
我们只要先求出每个人最后赢的场数,就可以直接算出不合法的三元组数量,再用C(n,3)减去这个就是答案了。
那么如何快速计算每个人赢的场数呢?
考虑扫描线,把修改存在vector里,先倒着扫一遍,查询s[j] < s[i] 且 i赢j的个数;再倒着扫一遍,。。。。把修改看成区间异或,查询看成区间1的个数,然后这就是基本线段树操作了23333
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pb push_back
#define lc (o<<1)
#define mid (l+r>>1)
#define rc ((o<<1)|1)
const int maxn=100005;
vector<int> L[maxn],R[maxn];
int a[maxn],n,num[maxn],k,X,Y,len[maxn*4];
int win[maxn],le,ri,sum[maxn*4],tag[maxn*4],w;
ll ans=0; inline void maintain(int o){ sum[o]=sum[lc]+sum[rc];} inline void work(int o){ tag[o]^=1,sum[o]=len[o]-sum[o];} inline void pushdown(int o){
if(tag[o]){
tag[o]=0;
work(lc),work(rc);
}
} void build(int o,int l,int r){
len[o]=r-l+1;
if(l==r){ sum[o]=1; return;}
build(lc,l,mid);
build(rc,mid+1,r);
maintain(o);
} void update(int o,int l,int r){
if(l>=le&&r<=ri){ work(o); return;}
pushdown(o);
if(le<=mid) update(lc,l,mid);
if(ri>mid) update(rc,mid+1,r);
maintain(o);
} void query(int o,int l,int r){
if(l>=le&&r<=ri){ w+=sum[o]; return;}
pushdown(o);
if(le<=mid) query(lc,l,mid);
if(ri>mid) query(rc,mid+1,r);
} inline void solve(){
build(1,1,n); for(int i=n;i;i--){
ri=i; for(int j=L[i].size()-1;j>=0;j--) le=L[i][j],update(1,1,n); w=0,le=1,ri=i-1;
if(le<=ri) query(1,1,n);
win[i]+=w; // cout<<i<<' '<<w<<endl;
} memset(sum,0,sizeof(sum));
memset(tag,0,sizeof(tag)); for(int i=1;i<=n;i++){
le=i;
for(int j=R[i].size()-1;j>=0;j--) ri=R[i][j],update(1,1,n); w=0,le=i+1,ri=n;
if(le<=ri) query(1,1,n);
win[i]+=w; // cout<<i<<' '<<win[i]<<endl;
} for(int i=1;i<=n;i++) ans-=win[i]*(ll)(win[i]-1)>>1;
} int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",a+i),num[i]=a[i]; sort(num+1,num+n+1);
// unique(num+1,num+n+1);
for(int i=1;i<=n;i++) a[i]=lower_bound(num+1,num+n+1,a[i])-num; while(k--){
scanf("%d%d",&X,&Y);
X=lower_bound(num+1,num+n+1,X)-num;
Y=upper_bound(num+1,num+n+1,Y)-num-1; if(!X||!Y) continue; L[Y].pb(X),R[X].pb(Y);
} ans=n*(ll)(n-1)*(ll)(n-2)/6ll,solve(); cout<<ans<<endl; return 0;
}
CodeForces - 283E Cow Tennis Tournament的更多相关文章
- 283E&EZOJ #89 Cow Tennis Tournament
传送门 分析 我们考虑用所有的情况减去不合法的情况 不难想出所有情况为$C_n^3$ 于是我们考虑不合法的情况 我们知道对于一个不合法的三元组$(a,b,c)$一定是修改后$a<b,b>c ...
- Educational Codeforces Round 8 A. Tennis Tournament 暴力
A. Tennis Tournament 题目连接: http://www.codeforces.com/contest/628/problem/A Description A tennis tour ...
- Codeforces CF#628 Education 8 A. Tennis Tournament
A. Tennis Tournament time limit per test 1 second memory limit per test 256 megabytes input standard ...
- CF 628A --- Tennis Tournament --- 水题
CF 628A 题目大意:给定n,b,p,其中n为进行比赛的人数,b为每场进行比赛的每一位运动员需要的水的数量, p为整个赛程提供给每位运动员的毛巾数量, 每次在剩余的n人数中,挑选2^k=m(m & ...
- Codeforces 678E. Another Sith Tournament(概率DP,状压)
Codeforces 678E. Another Sith Tournament 题意: n(n<=18)个人打擂台赛,给定任意两人对决的胜负概率,比赛规则:可指定一人作为最开始的擂主,每次可指 ...
- Codeforces Educational Codeforces Round 8 A. Tennis Tournament
大致题意: 网球比赛,n个參赛者,每场比赛每位选手b瓶水+裁判1瓶水,所有比赛每一个參赛者p条毛巾 每一轮比赛有2^k个人參加比赛(k为2^k<=n中k的最大值),下一轮晋级人数是本轮每场比赛的 ...
- Codeforces 735C:Tennis Championship(数学+贪心)
http://codeforces.com/problemset/problem/735/C 题意:有n个人打锦标赛,淘汰赛制度,即一个人和另一个人打,输的一方出局.问这n个人里面冠军最多能赢多少场, ...
- CodeForces - 1209D Cow and Snacks 并查集
CodeForces - 1209D 题意 现在n种点心,每种点心只有一份,有k位客人,每位客人有两种想要吃的点心,你可以安排他们进场的顺序,每位客人会吃掉所有他想要吃的,并且还没被吃掉的点心.如果客 ...
- codeforces 678E Another Sith Tournament 概率dp
奉上官方题解 然后直接写的记忆化搜索 #include <cstdio> #include <iostream> #include <ctime> #include ...
随机推荐
- BZOJ 2500 幸福的道路(race) 树上直径+平衡树
structHeal { priority_queue<int> real; priority_queue<int> stack; void push(int x){ real ...
- Mockito中@Mock与@InjectMock
Mockito是java单元测试中,最常用的mck工具之一,提供了诸多打桩方法和注解.其中有两个比较常用的注解,@Mock和@InjectMock,名字和在代码中使用 的位置都很像,对于初学者,很容易 ...
- org.apache.hadoop.hdfs.server.datanode.DataNode: Exception in receiveBlock for block
Hbase依赖的datanode日志中如果出现如下报错信息:DataXceiverjava.io.EOFException: INFO org.apache.hadoop.hdfs.server.da ...
- centos7 mysql cluster集群搭建基于docker
1.准备 mn:集群管理服务器用于管理集群的其他节点.我们可以从管理节点创建和配置集群上的新节点.重新启动.删除或备份节点. db2/db3:这是节点间同步和数据复制的过程发生的层. db4/db5: ...
- HDU2553 N皇后问题---(dfs)
http://acm.hdu.edu.cn/showproblem.php?pid=2553 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在 ...
- 【Foreign】字符串匹配 [KMP]
字符串匹配 Time Limit: 10 Sec Memory Limit: 256 MB Description Input Output Sample Input 3 3 6 3 1 2 1 2 ...
- codeforce C. Okabe and Boxes
题目传送门 这道题 每次删除一个点 那么这个点必然在栈里面 那么如果堆顶不是他 我们就需要一次操作使得堆合理 这时我们可以把他删除然后把他下面的点打个标记表示这下面的点以后想怎么排就怎么排以后都不需要 ...
- bzoj 2190 线性生成欧拉函数表
首先我们知道,正方形内个是对称的,关于y=x对称,所以只需要算出来一半的人数 然后乘2+1就行了,+1是(1,1)这个点 开始我先想的递推 那么我们对于一半的三角形,一列一列的看,假设已经求好了第I- ...
- Linux 内核链表的使用及深入分析【转】
转自:http://blog.csdn.net/BoArmy/article/details/8652776 1.内核链表和普通链表的区别 内核链表是一个双向链表,但是与普通的双向链表又有所区别.内核 ...
- 常见协议基础知识总结--FTP协议
FTP协议是一种基于客户端和服务器的文件传输协议,属于应用层协议,基于传输层的TCP协议: FTP主要分成主动模式和被动模式两种传输方式, 方式是相对服务器而言的,服务器主动发起数据连接即主动方式,使 ...