说实话,题我没大读懂。
听zwz大佬说这个题挑战者的两个能力值不能与被挑战者能力值相等,不过可以取实数,所以这句话看没看到都不影响这个思路,因为每个相等的数都可以+0.1或-0.1来实现不相等且不影响答案,所以以下按照能力值可以相等来讲比较清楚,具体的还是看下面吧。。。
以下设挑战者(能力值不固定的人)为A,给出的n个人都为B。
这个题容易被两个能力值限制住思维,觉得两个变量应该放在一起看。先说一下怎么做。我们尝试是否可以把两个值分开看。而考虑单个值的贡献时候,显然只需要考虑A在[0,n+1][0,n+1][0,n+1]的贡献,0为全输,n+1为全赢。那么对于B一个能力值 x ,当且仅当A的能力值 >x 的时候才能有贡献(注意是要大于)。那么对于每个 x ,可以利用差分将[x+1,n+1][x+1,n+1][x+1,n+1]全加一。对于前后两个能力值都这么做一遍,让后得到两个A前后能力值在[0,n+1][0,n+1][0,n+1]的贡献,去重之后求一下两个数组每个数相加之后能得到的不同数的数量即为答案。至于这个怎么求,显然有个O(n2)O(n^2)O(n2)的算法(划掉,让后lcdl用FFT O(NlogN)O(NlogN)O(NlogN)秒了(在线%lc学长)。把两个数组看成两个多项式,数组元素看成多项式的指数,将其系数设为1,让后乘起来之后看看有几项系数不为1即可。
下面瞎扯一下为啥是对的。
我们可以想想胜利的2分怎么来的(为了避免小数,我都乘了2),显然是A的两个能力值都大于B的。那么如果只有其中一个大于,另一个小于,得分是不是应该也取一半呢?显然这种是平局得分为1=2/2。再看输的情况显然为0。两个能力值对应两分,一个能力值对应一分,零个能力值对应零分,而且最终还是算总分。这种种巧合不就是暗示我们可以分开看嘛。。。就是左边能力值取[0,n+1][0,n+1][0,n+1]之间一个值,右边也是取[0,n+1][0,n+1][0,n+1]之间一个值,两个的贡献加起来不就是总得分嘛,而且我们可以处理出他们的贡献,显然这种方法正确。

虽然我不会FFT,但是某谷有板子啊。
我把我的代码和板子分开了,可读性能高点吧。。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#define pb push_back
using namespace std;
const int MAXN=1e7+10;
inline int read()
{char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
//以下为板子
const double Pi=acos(-1.0);
struct complex
{double x,y;complex (double xx=0,double yy=0){x=xx,y=yy;}
}a[MAXN],b[MAXN];
complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);}
complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);}
complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);}
int N,M;
int l,r[MAXN];
int limit=1;
void fast_fast_tle(complex *A,int type)
{for(int i=0;i<limit;i++)if(i<r[i]) swap(A[i],A[r[i]]);for(int mid=1;mid<limit;mid<<=1){complex Wn( cos(Pi/mid) , type*sin(Pi/mid) );for(int R=mid<<1,j=0;j<limit;j+=R){complex w(1,0);for(int k=0;k<mid;k++,w=w*Wn){complex x=A[j+k],y=w*A[j+mid+k];A[j+k]=x+y;A[j+mid+k]=x-y;}}}
}
//以上为板子
int n,cnt;
int aa[MAXN],bb[MAXN];
int p1[MAXN],p2[MAXN];void change(vector<int>&v)
{sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
}
int main()
{//以下处理两个能力值[0,n+1]的贡献scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&aa[i],&bb[i]);p1[n+2]--; p1[aa[i]+1]++;p2[n+2]--; p2[bb[i]+1]++;}for(int i=1;i<=n+1;i++) p1[i]+=p1[i-1],p2[i]+=p2[i-1];vector<int>v1,v2;for(int i=0;i<=n+1;i++) v1.pb(p1[i]),v2.pb(p2[i]);change(v1); change(v2);N=v1.size(),M=v2.size();for(int i=0;i<N;i++) a[v1[i]].x=1;for(int i=0;i<M;i++) b[v2[i]].x=1;
//以下为板子
//-------------------------------------------------------------------N=n+1,M=n+1;while(limit<=N+M) limit<<=1,l++;for(int i=0;i<limit;i++)r[i]= ( r[i>>1]>>1 )| ( (i&1)<<(l-1) ) ;fast_fast_tle(a,1);fast_fast_tle(b,1);for(int i=0;i<=limit;i++) a[i]=a[i]*b[i];fast_fast_tle(a,-1);int ans=0;//-------------------------------------------------------------------
//以上为板子for(int i=0;i<=N+M;i++)if((int)(a[i].x/limit+0.5)>=1) ans++;printf("%d\n",ans);return 0;
}

upc Cafebazaar’s Chess Tournament 思维 + FFT相关推荐

  1. 中石油训练赛 - Cafebazaar’s Chess Tournament(FFT)

    题目大意:给出 n 个队伍,每个队伍有两个属性分别记为 a 和 b ,如果队伍 i 和队伍 j 比赛: a[ i ] > a[ j ] && b[ i ] > b[ j ] ...

  2. Chess Tournament(思维题)

    题目 Chess Tournament 问题描述 有nnn个人参加比赛,两两之间进行对决,每两个人之间都会进行一次比赛: 对决有三种结果:要么胜,要么败,要么平. 选手有两种策略: 第一种:全场不败, ...

  3. CF1569B. Chess Tournament 简单思维

    B. Chess Tournament​​​​​​​ 题意:n个人 每两人间进行一次比赛,结果有胜平负三种.每个人要求1.不负 或2.至少胜一场, 给出n个人的要求(1or2),求能否满足所有人的要求 ...

  4. CodeForces - 1569B Chess Tournament

    CodeForces - 1569B AYIT609第一周周赛(2021) A chess tournament will be held soon, where n chess players wi ...

  5. kattis Block Game + Chess Tournament + Completing the Square + Millionaire Madness

    这几道题都来自同一场比赛,这次把这几道题做一个整理.原题不说了,只说一下个别题的题目大意和思路. A - Block Game 一个玄学的博弈问题,虽然没看懂,但是做出来了. 这里只说一下必胜态,1如 ...

  6. Chess Tournament (巧用思维)

    文章目录 前言 个人理解 前言 开始一脸茫然-后来偷看了大佬的博客感觉超级nice,推一波 传送门 个人理解 感觉大佬的博客已经讲解的非常详细了,输出的结果只要满足: 1)整个方阵关于j=i这条线对称 ...

  7. 2021牛客多校1 - Hash Function(思维+FFT)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,现在要求找到一个 seedseedseed,使得所有数字变为 a[i]=a[i]modseeda[i]=a[i]\mod seeda[i] ...

  8. Chess DP 思维题

    車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子.一天,小度在棋盘上摆起了许多車--他想知道,在一共N×M个点的矩形棋盘中摆最多个数的車使其互不攻击的方案数.他经过思考,得出了 ...

  9. Colorful Slimes( UPC 5594: 二维dp+思维)

    5594: Colorful Slimes 时间限制: 2 Sec  内存限制: 256 MB 提交: 235  解决: 36 [提交][状态][讨论版][命题人:admin] 题目描述 Snuke ...

最新文章

  1. Java自学笔记(16):常用类:Math,Data和Calender,Format,Scanner
  2. Oracle redo
  3. API 层实现语音录制
  4. 服务器文件夹和电脑文件夹同步软件哪个好,windows文件同步备份软件-文件夹同步工具哪个好?...
  5. Confluence与Jira安装及后期迁移问题记录
  6. (转)TweenMax动画库学习(四)
  7. 程序人生:程序员做外包“前途“,“技术“,“经验“如何决策
  8. python3.6 - threading 多线程编程基础(1)
  9. Backbone.js Wine Cellar 教程
  10. 小米路由器显示DNS服务器设置错误,小米路由器dns异常怎么修复
  11. 什么叫弹性计算云服务器,弹性云服务器
  12. 基于 Verilog 的经典数字电路设计(3)选择器
  13. 上twitter_如何在Twitter上找到重大新闻
  14. ECC椭圆曲线加密的特点以及在有限域(Fp)的三点共线问题
  15. 紅米android os,红米7A 魔趣OS 安卓10 纯净完美 原生极简 纯净推荐
  16. 在CMD中输入adb命令,提示“‘adb‘ 不是内部或外部命令,也不是可运行程序或批处理文件”的解决方法
  17. navigation Bar、toolBar、tabbar 区别
  18. 数据仓库面试题-初级
  19. 1C.小a与星际探索(C++)
  20. [热门]浅谈360主动防御(360提示)、瑞星主动及360实时查杀的免杀技巧

热门文章

  1. java 股票交易系统_JAVA程序实现股票交易系统设计
  2. centernet代码阅读笔记
  3. python列表合并降序排列_python对象列表,根据对象属性以降序排列
  4. java学生成绩降序代码_输入5名学员成绩,降序排列输出
  5. 教您如何查看Win7详细系统版本号
  6. python绘制三维地形shade()参数_python中的Matplot库和Gdal库绘制富士山三维地形图-参考了虾神的喜马拉雅山...
  7. 计算机开机总要按f1键,华硕主板开机需要按F1键怎么解决?华硕主板开机按f1的解决方法...
  8. 使用AWK和XARGS为文件批量改名
  9. sencha app watch php,Sencha Cmd使用指南
  10. php反序列化漏洞中当不存在__invoke时的一种利用思路