2016 Multi-University Training Contest 10
2016-12-07 22:34
246 查看
开始刷多校,今天第一弹。
话说,多校的题目真的好难。。。
要求新序列的中位数。
分三种情况考虑。
1.区间没交集。
2.区间半交。
3.区间全包裹。
各自找到自己的位置就好。
先算i在第几轮死掉。有方程f[i]=i%k?f[i-i/k-1]+1:0;
然后累计前面死的人的个数就好了。
前几轮死的人说 a[i]=i%k?a[i-i/k-1]:i/k+1;
加上预处理的left[f[i]]即可。
参考线段树扫描线做法。
对于横着的线段,左端点+1,右端点-1。这样累计的时候可以巧妙的去掉没有交点的线。对于竖着的线段,就查询。
处理的时候需要离散化。
以及ans要用long long
模拟题。
特殊处理1-19。20-1000的话直接算个位十位+百位就行了。
话说,多校的题目真的好难。。。
Median HDU 5857
给定一个有序序列,然后给定两个区间[l1,r1],[l2,r2]产生新的序列。要求新序列的中位数。
分三种情况考虑。
1.区间没交集。
2.区间半交。
3.区间全包裹。
各自找到自己的位置就好。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int a[100005]; int T,n,m,l1,l2,r1,r2; double find(int a[],int x){ if(r1<=l2){ if(x<=r1-l1+1) return a[l1+x-1]; else return a[l2+x-1-r1+l1-1]; } else if(r1<=r2){ if(x<=l2-l1) return a[l1+x-1]; else if(x>r1-l1+1+r1-l2+1) return a[l2+x-r1+l1-1-1]; else return a[l2+(x-l2+l1+1)/2-1]; } else{ swap(r1,r2); // l1,r2,r1,l2 if(x<=l2-l1) return a[l1+x-1]; else if(x>r1-l1+1+r1-l2+1) return a[l2+x-r1+l1-1-1]; else return a[l2+(x-l2+l1+1)/2-1]; } } int main(){ cin>>T; while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&l1,&r1,&l2,&r2); d42a int len = r1-l1+1 + r2-l2+1; if(l1>l2){ int t =l1;l1=l2;l2=t; t =r1;r1=r2;r2=t; } double mid; if(len&1) mid = find(a,len/2+1); else mid = 0.5*find(a,len/2) + 0.5*find(a,len/2+1); printf("%.1lf\n",mid); } } return 0; }
Hard problem
解析几何吧。先建系算出交点的坐标,然后就能算出来了。#include <cstdio> #include <cmath> #include <iostream> using namespace std; double calc(int l){ double t1 = asin(sqrt(14.0)/8.0); double t2 = asin(sqrt(14.0)/4.0); double s2 = l * l * 1.0 / 8 * t2 * 2; double s1 = l * l * 1.0 / 2 * t1 * 2 - sqrt(7) / 8 * l * l; return (s2 - s1)*2.0; } int main(){ int T,l; cin>>T; while(T--){ cin>>l; printf("%.2lf\n",calc(l)); } return 0; }
Death Sequence
动规题。先算i在第几轮死掉。有方程f[i]=i%k?f[i-i/k-1]+1:0;
然后累计前面死的人的个数就好了。
前几轮死的人说 a[i]=i%k?a[i-i/k-1]:i/k+1;
加上预处理的left[f[i]]即可。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 3000010; int ans[MAXN],f[MAXN],a[MAXN],LEFT[MAXN]; int T,n,k,q,x; void solve(){ int t = n; int tot = 0; LEFT[0] = 0; while(t){ tot++; LEFT[tot] = LEFT[tot-1]+(t-1)/k+1; t-=(t-1)/k+1; } memset(f,0,sizeof(f)); memset(a,0,sizeof(a)); for(int i=0;i<n;i++){ f[i]=(i%k)?f[i-i/k-1]+1:0; a[i]=(i%k)?a[i-i/k-1]:i/k+1; } for(int i=0;i<n;i++){ int t=LEFT[f[i]]+a[i]; ans[t]=i; } } int main(){ cin>>T; while(T--){ memset(ans,0,sizeof(ans)); scanf("%d%d%d",&n,&k,&q); solve(); for(int i=1;i<=q;i++){ scanf("%d",&x); printf("%d\n",ans[x]+1); } } return 0; }
Counting Intersections
给定一系列平行于坐标轴的直线,求其交点的个数。参考线段树扫描线做法。
对于横着的线段,左端点+1,右端点-1。这样累计的时候可以巧妙的去掉没有交点的线。对于竖着的线段,就查询。
处理的时候需要离散化。
以及ans要用long long
#include <cstdio> #include <cstring> #include <iostream> #include <climits> #include <algorithm> #include <map> #define LL long long using namespace std; const int MAXN = 100005; struct node{ int tp,x,y,y2; }info[MAXN*2]; int a[MAXN*2],sum[MAXN*2],Maxn; map<int,int> mp; bool cmp(node a,node b){ return (a.x<b.x)||(a.x==b.x&&a.tp<b.tp); } void insert(int BIT,int tp,int x,int y,int y2){ info[BIT].tp=tp; info[BIT].x = x; info[BIT].y = y; info[BIT].y2=y2; } int lowbit(int k){return k&(-k);} void add(int k,int delta){ while(k<=Maxn){ sum[k]+=delta; k+=lowbit(k); } } int query(int k){ int s = 0; while(k){ s+=sum[k]; k-=lowbit(k); } return s; } int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); int tot=0,all=0; for(int i=1;i<=n;i++){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1==x2){//竖 1 if(y1>y2) swap(y1,y2); insert(++tot,1,x1,y1,y2); a[++all]=y1; a[++all]=y2; } else {//横 0 if(x1>x2) swap(x1,x2); insert(++tot,0,x1,y1,1); insert(++tot,0,x2+1,y2,-1); a[++all]=y1; } } sort(a+1,a+1+all); int cnt = 0; mp.clear(); for(int i=1;i<=all;i++) if(!mp[a[i]]) mp[a[i]]=++cnt; Maxn = cnt + 1; memset(sum,0,sizeof(sum)); sort(info+1,info+1+tot,cmp); LL ans = 0; for(int i=1;i<=tot;i++){ if(info[i].tp==0){ int tp = mp[info[i].y]; add(tp,info[i].y2); } else { int l = mp[info[i].y],r=mp[info[i].y2]; ans += query(r) - query(l-1); } } printf("%I64d\n",ans); } return 0; }
Water problem
求 1~n 这n个数字的英文写法的总长度. (不算空格和连字符)模拟题。
特殊处理1-19。20-1000的话直接算个位十位+百位就行了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int bit1[] = {4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}; int bit2[] = {0,0,6,6,5,5,5,7,6,6}; int hundred, thousand; int cnt[1100]; void solve(){ hundred = 7; thousand = 8; cnt[1000] = 11; for(int i=1; i<1000; i++) { if(i < 20) cnt[i] = bit1[i]; else if(i < 100){ int m = i; cnt[i] = bit2[m/10]; if(m%10) cnt[i] += bit1[m%10]; } else { int m = i; cnt[i] = bit1[m/100] + hundred; if(!(m%100)) continue; cnt[i] += cnt[m%100] + 3; } } for(int i=1; i<=1000; i++) cnt[i] += cnt[i-1]; } int main(){ solve(); int T; cin>>T; while(T--){ int n; scanf("%d",&n); printf("%d\n",cnt ); } return 0; }
相关文章推荐
- AIX下使用ACFS的bug
- Error:scalac: Error: scala/tools/nsc/Main : Unsupported major.minor version
- A. Arpa’s hard exam and Mehrdad’s naive cheat
- weblogic管理1——创建 和 删除一个domain
- xenomai 在ubuntu上的安装测试
- solr6.3.0 定时增量更新配置·真
- 图像处理(二十四)Gradient Domain High Dynamic Range Compression学习笔记
- Codeforces Round #383 (Div. 2) A. Arpa’s hard exam and Mehrdad’s naive cheat(水题)
- 如何删除Main.storyboard而使用xib文件构建界面
- leetcode note--leetcode 11 Container With Most Water
- HA Cluster 之 OpenAIS---corosync
- CodeForces 742A Arpa’s hard exam and Mehrdad’s naive cheat
- linker command failed with exit code 1 (use -v to see invocation)报错
- 用闭包实现ipairs
- rails 手动创建controller和model 用和model名不同的数据表 会产生的问题
- linker command failed with exit code 1 (use -v to&n
- LINK1123:failure during conversion to COFF:file invalid or corrupt
- Failure to find xxx in xxx was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced @ xxx
- wait、notify、notifyAll的阻塞和恢复
- 第一日:Failed to load the JNI shared library jvm.dll