【XJOI】【NOI考前模拟赛7】

DP+卡常数+高精度/  计算几何+二分+判区间交/  凸包



  首先感谢徐老师的慷慨,让蒟蒻有幸膜拜了学军的神题。祝NOI2015圆满成功

  同时膜拜碾压了蒟蒻的众神QAQ

填填填

  我的DP比较逗比……(当时看到其他大神有更加优秀的做法)

  f[i][j]表示前 i 个数,第一行填了 j 个的方案数,那么如果 i 并没有固定位置,f[i][j]=f[i-1][j]+f[i-1][j-1];即 i 这个数放在第一行或是第二行。。。(废话)

  如果 i 固定的位置是第一行(1,y),那么f[i]中只有f[i][y]=f[i-1][y-1];(这个数一定放在第一行)

  如果 i 固定的位置是第二行(2,y),那么f[i]中只有f[i][i-y]=f[i-1][i-y];(一定放在第二行)

  这个DP是会爆空间的,但是我们发现f[i]只跟f[i-1]有关,所以滚动数组优化一下就好了……(我一开始还在蛋疼高精度的数组开不下)

  我比较傻逼,不知道XJOI是不能用#ifndef ONLINE_JUDGE的,所以第一题没删文件操作……爆零滚粗了,删掉后是70分,两RE四TLE。

  然后开始了漫漫卡常之路……比如高精从int压9位改成long long压17位,高精加的过程用指针实现(Orz Davidlee1999)

  RE的那两个点是怎么回事呢?因为如果 i 固定的位置是第二行的时候,i-y可能会越界!(也就是无法得到一组合法解)那么这个时候我需要特判一下……

 1 //XJOI test7 A
 2 #include<ctime>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 #define pb push_back
13 using namespace std;
14 inline int getint(){
15     int v=0,sign=1; char ch=getchar();
16     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
17     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
18     return v*sign;
19 }
20 const int N=4010,INF=~0u>>2;
21 typedef long long LL;
22 /******************tamplate*********************/
23
24 struct bint{
25     LL a[50],l;
26     bint(){l=0;memset(a,0,sizeof a);}
27     LL& operator [] (int x){return a[x];}
28 }f[2][N];
29 const LL Limit=100000000000000000LL;
30 void print(bint a){
31     printf("%lld",a[a.l]);
32     D(i,a.l-1,1) printf("%017lld",a[i]);
33     puts("");
34 }
35 bint operator + (bint a,bint &b){
36     LL *it1=a.a+1,*it2=b.a+1;
37     int l=max(a.l,b.l);
38     F(i,1,l){
39         *it1+=*it2;
40         it1++; it2++;
41     }
42     it1=a.a+1,it2=a.a+2;
43     F(i,1,l){
44         if (*it1>=Limit) *it1-=Limit,(*it2)++;
45         it1++; it2++;
46     }
47     if (a[l+1]>0) a.l=l+1; else a.l=l;
48     return a;
49 }
50 int n,v[3][N];
51 typedef pair<int,int> pii;
52 #define mp make_pair
53 #define fi first
54 #define se second
55 pii pos[N];
56
57
58 int main(){
59 //  time_t start,end; start=clock();
60     n=getint();
61     F(i,1,2) F(j,1,n){
62         v[i][j]=getint();
63         if (v[i][j]) pos[v[i][j]]=mp(i,j);
64     }
65     f[0][0].l=f[0][0][1]=1;
66     F(i,1,2*n){
67         int now=i&1;
68         if (pos[i].fi==1){
69             int j=pos[i].se;
70             f[now][j]=f[now^1][j-1];
71         }else if (pos[i].fi==2){
72             int j=i-pos[i].se;
73             if (j<=0){printf("0\n"); return 0;}
74             f[now][j]=f[now^1][j];
75         }else{
76             F(j,(i+1)/2,min(i,n)){
77                  f[now][j]=f[now^1][j-1]+f[now^1][j];
78 //                 f[now][j]=f[now][j]+f[now^1][j];
79             }
80         }
81         F(j,i/2,min(i-1,n)) f[now^1][j]=bint();
82     }
83     print(f[0][n]);
84 /*  end=clock();
85     cout <<"start : "<<start<<endl;
86     cout <<"end : "<<end<<endl;
87     cout <<"time : "<<double(end-start)/CLOCKS_PER_SEC<<endl;
88 */  return 0;
89 }

线线线

  计算几何QAQ

  这题……倒是很容易想到可以二分这个dist,那么对于$S$中的每一个点,以它为圆心,dist为半径画一个圆,只要直线与这个圆的交集不为空那么这个圆就可以满足了……那么满足条件的直线所组成的明显是个扇形(只看一侧的话,因为是直线,两边加起来是对称的两个扇形)。

  然而我并不会算扇形的交……(由此可见多么傻逼)

  想到这里我就弃疗了……没有写……连暴力都不会……

  然而其实并不用算扇形交= =因为这个直线不是过定点嘛,那么所谓扇形……其实就是极角对应的区间罢了!所以其实就是求区间交!找是否有一段被n个区间覆盖即可……注意由于是直线,所以反向的那一边穿过去也可以……所以一个$S$中的点应该是对应两个区间!(Orz zld神犇)

  进入区间+1,离开区间-1,每个区间的左右端点都视为一个事件,排序一下,看是否某一时刻前缀和为n即可。

 1 //XJOI test7 B
 2 //Orz zld大爷
 3 #include<vector>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<cstdlib>
 8 #include<iostream>
 9 #include<algorithm>
10 #define rep(i,n) for(int i=0;i<n;++i)
11 #define F(i,j,n) for(int i=j;i<=n;++i)
12 #define D(i,j,n) for(int i=j;i>=n;--i)
13 #define pb push_back
14 using namespace std;
15 inline int getint(){
16     int v=0,sign=1; char ch=getchar();
17     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
18     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
19     return v*sign;
20 }
21 const int N=120000,INF=~0u>>2;
22 typedef long long LL;
23 const double eps=1e-8,pi=acos(-1);
24 #define sqr(x) ((x)*(x))
25 /******************tamplate*********************/
26
27 int n;
28 double tx,ty;
29 double a[N],dis[N];
30 typedef pair<double,int> pii;
31 #define mp make_pair
32 pii c[N*6];
33 bool check(double d){
34     int s=0,tot=0;
35     F(i,1,n)
36         if (dis[i]<=d) s++;
37         else{
38             double l=asin(d/dis[i]);
39             c[++tot]=mp(a[i]-l,1);
40             c[++tot]=mp(a[i]+l,-1);
41             if (a[i]>0){
42                 c[++tot]=mp(a[i]-pi-l,1);
43                 c[++tot]=mp(a[i]-pi+l,-1);
44             }else{
45                 c[++tot]=mp(a[i]+pi-l,1);
46                 c[++tot]=mp(a[i]+pi+l,-1);
47             }
48         }
49     sort(c+1,c+tot+1);
50     F(i,1,tot){
51         s+=c[i].second;
52         if (s==n) return 1;
53     }
54     return 0;
55 }
56 int main(){
57 //  freopen("B.in","r",stdin);
58     n=getint(); tx=getint(); ty=getint();
59     double l=0,r=0;
60     F(i,1,n){
61         double x=getint(),y=getint();
62         a[i]=atan2(x-tx,y-ty);
63         dis[i]=sqrt(sqr(x-tx)+sqr(y-ty));
64         r=max(dis[i],r);
65     }
66     while(r-l>eps){
67         double mid=(l+r)/2;
68         if (check(mid)) r=mid;
69         else l=mid;
70     }
71     int ans=floor(l*1000);
72     printf("%d.%03d\n",ans/1000,ans%1000);
73 //  printf("%.3f\n",l-0.0005);
74     return 0;
75 }

凸凸凸

  蒟蒻并不会啊……码了个暴力凸包,40分

  正解好像是这样的……

  矩形框内离上边界最近的点Up,下边界最近的点Down,左Left,右Right,这四个点一定在最终的凸包上……

  所以只要预处理出来这四个点之间的凸壳,就可以快速回答询问了QAQ

  这个好像是满足一个树形的结构?然而蒟蒻并不会写……sad

 1 //XJOI test7 C
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 inline int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
16     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
17     return v*sign;
18 }
19 const int N=6010,INF=~0u>>2;
20 typedef long long LL;
21 /******************tamplate*********************/
22
23 struct Poi{
24     int x,y;
25     Poi(){}
26     Poi(int x,int y):x(x),y(y){}
27     void read(){x=getint(),y=getint();}
28 }p[N],a[N],st[N],O(0,0);
29 typedef Poi Vec;
30 bool operator < (const Poi &a,const Poi &b){return a.x<b.x ||(a.x==b.x && a.y<b.y);}
31 Vec operator - (Poi a,Poi b){return Vec(a.x-b.x,a.y-b.y);}
32 double Cross(const Poi &a,const Poi &b){return (double)a.x*b.y-(double)a.y*b.x;}
33
34 int n,m,top,k;
35
36 void solve(){
37     top=0;
38     F(i,1,m){
39         while(top>1 && Cross(st[top]-st[top-1],a[i]-st[top-1])<=0) top--;
40         st[++top]=a[i];
41     }
42     int k=top;
43     D(i,m,1){
44         while(top>k && Cross(st[top]-st[top-1],a[i]-st[top-1])<=0) top--;
45         st[++top]=a[i];
46     }
47     double ans=0.0;
48     F(i,1,top-1) ans+=Cross(st[i]-O,st[i+1]-O)/2;
49     printf("%.1f\n",ans);
50 }
51
52 int main(){
53     k=getint(); n=getint();
54     F(i,1,n) p[i].read();
55     sort(p+1,p+n+1);
56     int q=getint();
57     F(i,1,q){
58         m=0;
59         int x1=getint(),x2=getint(),y1=getint(),y2=getint();
60         F(i,1,n) if (p[i].x>=x1 && p[i].x<=x2 && p[i].y>=y1 && p[i].y<=y2)
61             a[++m]=p[i];
62         solve();
63     }
64     return 0;
65 }

时间: 2024-11-06 05:35:27

【XJOI】【NOI考前模拟赛7】的相关文章

2017.11.8 Noip2017 考前模拟赛

----------------------------------T1---------------------------------- ——>足球联赛 题目描述 巴蜀中学新一季的足球联赛开幕了. 足球联赛有 n 只球队参赛,每赛季,每只球队要与其他球队各赛两场,主客各一场,赢一场得 3 分,输一场不得分,平局两只队伍各得一分. 英勇无畏的小鸿是机房的主力前锋, 她总能在关键时刻踢出一些匪夷所思的妙球. 但是很可惜,她过早的燃烧完了她的职业生涯,不过作为一个能够 Burning 的 girl

xjoi省选模拟赛_14

T1 发现 对于当前 投出 奇数次向上的概率为 p 那么 若加入一个 pi=0.5 的骰子 发现  p奇 +1=p奇 * 0.5+p偶 * 0.5 = p偶+1  也就是说 只要方案中存在一个 p=0.5 的骰子 这个方案必然合法  : 1 #include <bits/stdc++.h> 2 #define N 100 3 #define eps 1e-7 4 using namespace std; 5 typedef long double ldb; 6 int t,n; 7 ldb A

【NOIP考前模拟赛】纯数学方法推导——旅行者问题

一.写在前面 这题似乎是一道原创题目(不是博主原创),所以并不能在任何OJ上评测,博主在网盘上上传了数据(网盘地址:http://pan.baidu.com/s/1mibdMXi),诸位看官需者自取.另外博主使用此题并没有获得出题人授权,如果出题人看到这篇blog并认为在下侵犯了您的权利,请用站内消息与在下联系,在下会立即删除这篇blog,给您带来的困扰之处敬请谅解. 博主上传这道题主要是因为这题牵扯许多数学运算,推导过程比较复杂,但是却没有用到任何算法或者数学定理,可以说这是一道想法题的典范.

NOI模拟赛 Day1

[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧张起来!!! 好了不扯淡了...

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):

9.14 模拟赛

模拟赛第三弹~ T1 题意:给你一个数列,要求删掉任意一种整数,使得剩下的新数列中连续的相等的数最多 例如 2 7 3 7 7 3 3 7 7 5 7,删掉3以后剩的7有四个连续的,最多 思路:暴力枚举去掉哪个......这算是一道水题吧 代码丢了...... TAT T2 题意:有n本书,每本书有宽度和高度.现在你有无数个书架,每个书架的宽度为w,高度由最高的书决定 问在书本按顺序放的情况下,总的书架高度最小是多少 思路:dp,dp[i]表示做到第i本书时的最小高度和. 每次先找到能以编号j的

2014-9-9 NOIP模拟赛

东方幻想乡系列模拟赛Stage 1命题 Nettle审题 Barty ccy1991911 FlanS39 Wagner T2 高精除高精,从来没写过,不知道怎么写,我就用大数减小数ans次,果断超时. T4 Tarjan的板子题,好久没写,中间出现了一些小错误 ①是尽管有双向边,Tarjan函数中也不必排除双向边 ②Tarjan算法有时候不能一步完成,需要做最多n次,用循环解决 ③问题是关于这个题目的虽然输入n代表有n个点,但是下面的连边中有些点根本没出现过,所以设一个数组记录有效点. Pro