【map的函数,离线线段树】 codeforces 365 div2
2016-08-08 17:19
357 查看
不错的文章
写全了map 的各种函数
http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html
顺便写一下
cf 365 div2 题目
A比大小,谁赢得多谁就赢了,有平局
题意:
B
一个无向图, n个城市,形成一个圈。
有k个城市比较特殊,这些个城市要和所有其他的城市都相连起来。每个城市有一个值, 每条边的值 是a*b(起点和终点两个城市值a,b)
虽然一发过,但耗费的时间也委实久了些
可能我写的比较麻烦吧: 用两个前缀和,一个代表总城市价值和
一个代表首都城市 的前缀和。
然后我们先建立起来一个完全图, 再一条边一条边的删除。
对于每一个城市,如果这个城市是首都,则先删去他和其他后面城市的边,再加上他和其他后面的首都的边。然后再加上他和他后面的城市的边。
如果他不是首都,则先删去他和其他城市的边,然后再加上他和所有首都的边,然后再加上他和他后面的城市的边。
总之好像我写的麻烦了。。。
C
一个多边形以 速度 v 在行驶= =,一个行人 以速度u过马路。然后问最短需要多久时间, 行人可以在半路上随时停 随时走。
一开始以为这是一个计算几何的题目,花了半天,发现好像忽视了随时可以停的条件。
选择的路线依然是笔直的走过去,路线不用去歪着走,就直走。如何要撞上了,我们就站着不动,等一会儿。
我们可以二分答案呢, 二分那个等待时间
因为2e9二分起来也不会太多,那对于每一个时间,我们如何判断呢,我们对于10000个点只要判断一下是否在每一个点的左边,或者在每一个点的右边即可,时间复杂度明显不会太高
注意处理一下别算出负数来了,坐标可能为负。
D
给一个序列
m次询问:
l,r 输出 al…..ar 出现次数为偶数次的 数的异或和
一开始没想清楚,觉得很难;
看了别人的题解
仔细想想发现是没想到点子上: 一段序列 出现次数为偶数次的数异或结果肯定为0;
所以一段序列 异或起来的结果肯定是出现次数为奇数次的数的异或 为 a
我们只要把一段序列去重,即把那些出现次数为偶数次的数变为1个,把出现次数为奇数次的数 变为1个 此为b
我们要求的出现次数为偶数次的数的异或 = a^b
a 一个前缀和 即可 : al…..ar = sum[r]^sum[l-1]
b 如何去重呢,离线的线段树可解决,等我把代码改好看一点再贴出来吧 (逃
写全了map 的各种函数
http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html
顺便写一下
cf 365 div2 题目
A比大小,谁赢得多谁就赢了,有平局
题意:
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<stdlib.h> #include<queue> #include<stack> #include<map> #include<vector> #define mem(a) memset(a,0,sizeof(a)) #define ll __int64 #define INF 0x7fffffff //INT_MAX #define inf 0x3f3f3f3f // const double PI = acos(-1.0); const double e = exp(1.0); template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } using namespace std; int main(){ int n; scanf("%d",&n); int a=0,b=0; while(n--){ int x,y; scanf("%d %d",&x,&y); if(x>y) a++; if(y>x) b++; } if(a>b){ printf("Mishka\n"); } else if(b>a){ printf("Chris\n"); } else printf("Friendship is magic!^^\n"); return 0; }
B
一个无向图, n个城市,形成一个圈。
有k个城市比较特殊,这些个城市要和所有其他的城市都相连起来。每个城市有一个值, 每条边的值 是a*b(起点和终点两个城市值a,b)
虽然一发过,但耗费的时间也委实久了些
可能我写的比较麻烦吧: 用两个前缀和,一个代表总城市价值和
一个代表首都城市 的前缀和。
然后我们先建立起来一个完全图, 再一条边一条边的删除。
对于每一个城市,如果这个城市是首都,则先删去他和其他后面城市的边,再加上他和其他后面的首都的边。然后再加上他和他后面的城市的边。
如果他不是首都,则先删去他和其他城市的边,然后再加上他和所有首都的边,然后再加上他和他后面的城市的边。
总之好像我写的麻烦了。。。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<stdlib.h> #include<queue> #include<stack> #include<map> #include<vector> #define mem(a) memset(a,0,sizeof(a)) #define ll __int64 #define INF 0x7fffffff //INT_MAX #define inf 0x3f3f3f3f // const double PI = acos(-1.0); const double e = exp(1.0); template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } using namespace std; int f[100005]; ll sum[100005]; int cap[100005]; int flag[100005]; ll sum2[100005]; int main(){ int n,m; scanf("%d %d",&n,&m); __int64 ans=0; sum[0]=0; ll all=0; for(int i=1;i<=n;i++){ scanf("%d",&f[i]); sum[i]=sum[i-1]+f[i]; ans+=f[i]*sum[i-1]; all+=f[i]; } // printf("ans=%I64d all=%I64d\n",ans,all); ll cnt=0; cap[0]=0; sum2[0]=0; for(int i=1;i<=m;i++){ scanf("%d",&cap[i]); sum2[cap[i]]=sum2[cap[i-1]]+f[cap[i]]; cnt+=f[cap[i]]; flag[cap[i]]=1; } for(int i=1;i<=n;i++){ if(!flag[i]){ ans-=(all-sum[i])*f[i]; ans+=cnt*f[i]; int r=i+1; if(r==n+1) r=1; if(!flag[r]) ans+=f[i]*f[r]; } else{ ans-=(all-sum[i])*f[i]; ans+=f[i]*(cnt-sum2[i]); } // printf("i=%d %I64d ans=%I64d\n",i,sum[i],ans); } printf("%I64d\n",ans); return 0; }
C
一个多边形以 速度 v 在行驶= =,一个行人 以速度u过马路。然后问最短需要多久时间, 行人可以在半路上随时停 随时走。
一开始以为这是一个计算几何的题目,花了半天,发现好像忽视了随时可以停的条件。
选择的路线依然是笔直的走过去,路线不用去歪着走,就直走。如何要撞上了,我们就站着不动,等一会儿。
我们可以二分答案呢, 二分那个等待时间
因为2e9二分起来也不会太多,那对于每一个时间,我们如何判断呢,我们对于10000个点只要判断一下是否在每一个点的左边,或者在每一个点的右边即可,时间复杂度明显不会太高
注意处理一下别算出负数来了,坐标可能为负。
#include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include<iomanip> #include <fstream> #include <map> #include <stack> #define ll long long #define pb push_back #define all(a) a.begin(), a.end() #define clean(a) memset(a, 0, sizeof(a)) typedef long double db; const db eps=1e-9; const int MAXN=10005; using namespace std; struct po{ db x,y; }f[100005]; int n; db w,v,u; bool jud(db time){ int l=0,r=0; //左,右边 for(int i=1;i<=n;i++){ if( (time+f[i].y/u )*v > f[i].x){ l=1; // cout<<time<<"ll "<<f[i].x<<" "<<f[i].y<<endl; } else{ r=1; // cout<<time<<"rr "<<f[i].x<<" "<<f[i].y<<endl;; } } if(l && r) return 0; return 1; } int main() { cin>>n>>w>>v>>u; for(int i=1;i<=n;i++) cin>>f[i].x>>f[i].y; cout<<fixed<<setprecision(12); if(jud(0)){ cout<<w/u<<endl; return 0; } db l=0,r=2e9; db ans=w/u; // cout<<ans<<" "; int ff=128; while(ff--){ db mid=(l+r)/2; if(jud(mid)) r=mid; else l=mid; } ans+=(l+r)/2; cout<<ans<<endl; return 0; }
D
给一个序列
m次询问:
l,r 输出 al…..ar 出现次数为偶数次的 数的异或和
一开始没想清楚,觉得很难;
看了别人的题解
仔细想想发现是没想到点子上: 一段序列 出现次数为偶数次的数异或结果肯定为0;
所以一段序列 异或起来的结果肯定是出现次数为奇数次的数的异或 为 a
我们只要把一段序列去重,即把那些出现次数为偶数次的数变为1个,把出现次数为奇数次的数 变为1个 此为b
我们要求的出现次数为偶数次的数的异或 = a^b
a 一个前缀和 即可 : al…..ar = sum[r]^sum[l-1]
b 如何去重呢,离线的线段树可解决,等我把代码改好看一点再贴出来吧 (逃
相关文章推荐
- [CF#365 (Div. 2) Mishka and Interesting sum] 线段树离线处理区间不同数
- 字符串q次操作将(l,r)内的字符升序或降序排列 计数排序 + 线段树优化 Codeforces div2 558E A Simple Task
- CodeForces 602B Approximating a Constant Range(方法很多,不想费脑子就上线段树)——Codeforces Beta Round #333 (Div. 2)
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树
- Codeforces Codeforces Round #316 (Div. 2) C. Replacement 线段树
- #Codeforces 343 [div2] D. Babaei and Birthday Cake 【线段树优先队列查询优化】
- 线段树离线处理(区间内出现k次的数有多少个)Codeforces Round #136 (Div. 2)
- codeforces div2 round388 D Voting 线段树
- [LCT维护最小生成树 || CDQ分治 || 线段树 并查集 dfs树] Codeforces 603E #334 (Div. 1) E. Pastoral Oddities
- CodeForces 173E Camping Groups 离线线段树 树状数组
- 【Codeforces Round 365 (Div 2)D】【离线询问 树状数组 前驱思想】Mishka and Interesting sum 区间内出现次数偶数的数的异或和
- Codeforces Round #136 (Div. 2) D. Little Elephant and Array 线段树 离线处理
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
- Codeforces 482B 线段树与离线区间加和问题
- HDU 4288 && Codeforces 85D (线段树+离散化+离线处理)
- Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
- [线段树] Codeforces 811E Round #416 (Div. 2) E. Vladik and Entertaining Flags
- codeforces 258-E. Little Elephant and Tree 线段树,离线
- [树上LIS 线段树合并] Codeforces 490F #279 (Div. 2) F. Treeland Tour