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 ...
随机推荐
- Codeforces ----- Kefa and Dishes [状压dp]
题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...
- n元线性方程非负整数解的个数问题
设方程x1+x2+x3+...+xn = m(m是常数) 这个方程的非负整数解的个数有(m+n-1)!/((n-1)!m!),也就是C(n+m-1,m). 具体解释就是m个1和n-1个0做重集的全排列 ...
- 安卓下拉刷新空间SwipeRefreshLayout的基本使用
1.先写布局文件 <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh" androi ...
- nginx 静态文件支持跨域访问权限
一.原生态 location ^~ /repurchase-web/ { alias /var/www/webapps/repurchase-web/; } 二.支持跨 ...
- fs.watch 爬坑
上星期用 fs.watch 和 readline.createInterface 对pm2的合并日志做了监控,根据指定的错误信息重启服务 发现不管是手动vim编辑日志,还是等待日志自动输出. fs.w ...
- Android 实现对图片 Exif 的修改(Android 自带的方法)
很多时候我们都要对我们的图片信息进行一些处理,比如向图片中写入经纬度,拍摄时间,设备信息,作者等等. 这个时候我们就要对我们的图片Exif进行写入信息的操作,当然,我们想知道图片的Exif信息,也可以 ...
- C++ 智能指针的简单实现
智能指针的用处:在c++中,使用普通指针容易造成堆内存的泄露问题,即程序员会忘记释放,以及二次释放,程序发生异常时内存泄漏等问题,而使用智能指针可以更好的管理堆内存.注意,在这里智能指针是一个类而非真 ...
- C# 文件类的操作---获取
如何获取指定目录包含的文件和子目录 . DirectoryInfo.GetFiles():获取目录中(不包含子目录)的文件,返回类型为FileInfo[],支持通配符查找: . DirectoryIn ...
- Python小程序之sed命令替换
需求: 编写sed命令脚本 代码如下 # Author:Lee Sir import sys,os des_file = r'E:\StartPython\day3\test.txt' des_fil ...
- scrapy的CrawlSpider使用
1.创建项目 我这里的项目名称为scrapyuniversal,然后我创建在D盘根目录.创建方法如下 打开cmd,切换到d盘根目录.然后输入以下命令: scrapy startproject scra ...