Beijing 2008 树状数组 ,LA 4329 Ping pong
2015-09-28 12:59
537 查看
题目:https://icpcarchive.ecs.baylor.edu/external/43/4329.pdf
考虑的方法是,依次考虑编号为i的人当裁判,然后计算出编号比他小且技能比他低的人ci个,和编号比他大且技能比他低的人di个
,那么编号比他小且技能比他高的人有 i-1-ci , 编号比他大且技能比他高的人有 n-i-di 个。
所以第i个人当裁判的情形= (i-1-ci)*di+ci*(n-i-di) ;
之前考虑时,总是固定 编号最高或者是技能最高的人,然后考虑从比他低的人中选两个,这样行不通。
本题还有一个关键就是,技能值各不相同,编号各不相同。
其实就算技能值出现相同的好像也可以解 :我先用技能值排个序,然后从小到大扫 。(利用编号一定不同)
我这样写其实有些麻烦,事先要把skill[]扫过一遍,更新D[]值。
因为,只需要知道ci、di 且ci,di是固定不变的,与扫描(/操作)过程无关.
故可以从右往左扫一次,把di存下来。
下面是佳神的代码。
考虑的方法是,依次考虑编号为i的人当裁判,然后计算出编号比他小且技能比他低的人ci个,和编号比他大且技能比他低的人di个
,那么编号比他小且技能比他高的人有 i-1-ci , 编号比他大且技能比他高的人有 n-i-di 个。
所以第i个人当裁判的情形= (i-1-ci)*di+ci*(n-i-di) ;
之前考虑时,总是固定 编号最高或者是技能最高的人,然后考虑从比他低的人中选两个,这样行不通。
本题还有一个关键就是,技能值各不相同,编号各不相同。
其实就算技能值出现相同的好像也可以解 :我先用技能值排个序,然后从小到大扫 。(利用编号一定不同)
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<climits> #include<queue> #include<vector> #include<map> #include<sstream> #include<set> #include<stack> #include<cctype> #include<utility> #pragma comment(linker, "/STACK:102400000,102400000") #define PI 3.1415926535897932384626 #define eps 1e-10 #define sqr(x) ((x)*(x)) #define FOR0(i,n) for(int i=0 ;i<(n) ;i++) #define FOR1(i,n) for(int i=1 ;i<=(n) ;i++) #define FORD(i,n) for(int i=(n) ;i>=0 ;i--) #define lson num<<1,le,mid #define rson num<<1|1,mid+1,ri #define MID int mid=(le+ri)>>1 #define zero(x)((x>0? x:-x)<1e-15) #define mk make_pair #define _f first #define _s second using namespace std; //const int INF= ; typedef long long ll; //const ll inf =1000000000000000;//1e15; //ifstream fin("input.txt"); //ofstream fout("output.txt"); //fin.close(); //fout.close(); //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); const int INF =0x3f3f3f3f; const int maxn= 20000+20 ; //const int maxm= ; //by yskysker123 const int N=100000; int skill[maxn]; ll ans; int n,C[100000+20],D[100000+20]; inline int lowbit(int x) { return x&(-x);} void add(int C[maxn],int x,int d) { while(x<=N) { C[x]+=d; x+=lowbit(x); } } int sum(int C[maxn],int x) { int ans=0; while(x) { ans+=C[x]; x-=lowbit(x); } return ans; } void work() { for(int i=1;i<=n;i++) { add(D, skill[i],1); } for(int i=1;i<=n;i++) { int cs=sum(C,skill[i]); int cl=i-1-cs; add(D,skill[i],-1); int ds=sum(D,skill[i]); int dl=n-i-ds; ans+= cs*dl+cl*ds; add(C,skill[i],+1); } } void init() { memset(C ,0,sizeof C); memset(D ,0,sizeof D); } int main() { int T;scanf("%d",&T); while(T--) { init(); scanf("%d",&n); FOR1(i,n) { scanf("%d",&skill[i]); } ans=0; work(); printf("%lld\n",ans); } return 0; }
我这样写其实有些麻烦,事先要把skill[]扫过一遍,更新D[]值。
因为,只需要知道ci、di 且ci,di是固定不变的,与扫描(/操作)过程无关.
故可以从右往左扫一次,把di存下来。
下面是佳神的代码。
// LA4329 Ping pong // Rujia Liu #include<cstdio> #include<vector> using namespace std; //inline int lowbit(int x) { return x&(x^(x-1)); } inline int lowbit(int x) { return x&-x; } struct FenwickTree { int n; vector<int> C; void resize(int n) { this->n = n; C.resize(n); } void clear() { fill(C.begin(), C.end(), 0); } // ¼ÆËãA[1]+A[2]+...+A[x] (x<=n) int sum(int x) { int ret = 0; while(x > 0) { ret += C[x]; x -= lowbit(x); } return ret; } // A[x] += d (1<=x<=n) void add(int x, int d) { while(x <= n) { C[x] += d; x += lowbit(x); } } }; const int maxn = 20000 + 5; int n, a[maxn], c[maxn], d[maxn]; FenwickTree f; int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); int maxa = 0; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); maxa = max(maxa, a[i]); } f.resize(maxa); f.clear(); for(int i = 1; i <= n; i++) { f.add(a[i], 1); c[i] = f.sum(a[i]-1); } f.clear(); for(int i = n; i >= 1; i--) { f.add(a[i], 1); d[i] = f.sum(a[i]-1); } long long ans = 0; for(int i = 1; i <= n; i++) ans += (long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-1)*d[i]; printf("%lld\n", ans); } return 0; }
相关文章推荐
- Ubuntu 10.04 下配置NFS并挂载共享目录到目标板上
- 二叉树的最小深度
- mysql创建存储过程 定时调用
- 【Linux命令-文件管理类】chgrp命令和groups命令
- PL/SQL Developer ORA-12154: TNS: 无法解析指定的连接标识符
- 好老板VS坏老板
- win10怎么设置高级黑?win10简单粗暴的个性化设置教程
- Java中关于HashMap的元素遍历的顺序问题
- 起始
- LR调用VC++6.0动态链接库
- 一键U盘启动快捷方式
- java 初始化(上)
- 二叉树的最大深度
- mysql 定时执行存储过程
- react-native —— 在Windows下搭建React Native Android开发环境
- 二叉树的前序遍历
- 二叉树的中序遍历
- 数据结构实验的目的、要求和评分标准
- USB设备的插入检测
- 完美的CListCtrl控件自绘