2017-10-28-morning-清北模拟赛

T1 立方数(cubic)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数。

现在给定一个数P,LYK想要知道这个数是不是立方数。

当然你有可能随机输出一些莫名其妙的东西来骗分,因此LYK有T次询问~

输入格式(cubic.in)

    第一行一个数T,表示有T组数据。

    接下来T行,每行一个数P。

输出格式(cubic.out)

输出T行,对于每个数如果是立方数,输出“YES”,否则输出“NO”。

输入样例

3

8

27

28

输出样例

YES

YES

NO

数据范围

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^18,T<=100。

二分是否存在使p为立方数的数 

 1 #include <cstdio>
 2 
 3 #define LL long long
 4 inline void read(LL &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>'9'||ch<'0'; ) ch=getchar();
 8     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
 9 }
10 LL L,R,Mid,tot;
11 
12 int Presist()
13 {
14 //    freopen("1.txt","r",stdin);
15     freopen("cubic.in","r",stdin);
16     freopen("cubic.out","w",stdout);
17     LL t; read(t);
18     for(LL p; t--; )
19     {
20         read(p);bool flag=0;
21         for(L=1,R=1e6+6; L<=R; )
22         {
23             Mid=L+R>>1;
24             tot=Mid*Mid*Mid;
25             if(tot==p)
26             {
27                 flag=1;
28                 break;
29             }
30             else if(tot<p) L=Mid+1;
31             else if(tot>p) R=Mid-1;
32         }
33         if(flag) puts("YES");
34         else puts("NO");
35     }
36     return 0;
37 }
38 
39 int Aptal=Presist();
40 int main(int argc,char**argv){;} 
AC

T2 立方数2(cubicp)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数。

LYK还定义了一个数叫“立方差数”,若一个数可以被写作是两个立方数的差,则这个数就是“立方差数”,例如7(8-1),26(27-1),19(27-8)都是立方差数。

现在给定一个数P,LYK想要知道这个数是不是立方差数。

当然你有可能随机输出一些莫名其妙的东西,因此LYK有T次询问~

这个问题可能太难了…… 因此LYK规定P是个质数!

输入格式(cubicp.in)

    第一行一个数T,表示有T组数据。

    接下来T行,每行一个数P。

输出格式(cubicp.out)

输出T行,对于每个数如果是立方差数,输出“YES”,否则输出“NO”。

输入样例

5

2

3

5

7

11

输出样例

NO

NO

NO

YES

NO

数据范围

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^12,T<=100。

 1 #include <cstdio>
 2 
 3 #define LL long long
 4 inline void read(LL &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>'9'||ch<'0'; ) ch=getchar();
 8     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
 9 }
10 LL L,R,Mid,l,r,mid,tmp,x,y;
11 
12 inline int check(LL oo)
13 {
14     LL ret=0;
15     for(l=1,r=1e4+6; l<=r; )
16     {
17         mid=l+r>>1;
18         x=mid*mid*mid;
19         if(x==oo) return 0;
20         else if(oo>x) l=mid+1,ret=1;
21         else if(oo<x) r=mid-1,ret=-1;
22     }
23     return ret;
24 }
25 
26 int Presist()
27 {
28 //    freopen("1.txt","r",stdin);
29 //    freopen("cubicp.in","r",stdin);
30 //    freopen("cubicp.out","w",stdout);
31     LL t; read(t);
32     for(LL p; t--; )
33     {
34         read(p);bool flag=0;
35         for(L=1,R=1e4+6; L<=R; )
36         {
37             Mid=L+R>>1;
38             y=Mid*Mid*Mid;
39             tmp=check(y-p);
40             if(tmp==0)
41             {
42                 flag=1;
43                 break;
44             }
45             else if(tmp>0) R=Mid-1;
46             else if(tmp<0) L=Mid+1;
47         }
48         if(flag) puts("YES");
49         else puts("NO");
50     }
51     return 0;
52 }
53 
54 int Aptal=Presist();
55 int main(int argc,char**argv){;} 
考试的逗比二分

p=x^3-y^3=(x-y)*(x^2+x*y+y^2),因为p为素数,

所以x-y=1,所以x=y+1,可以枚举y,检验是否存在p

 1 #include <cstdio>
 2 
 3 #define LL long long
 4 inline void read(LL &x)
 5 {
 6     x=0; register char ch=getchar();
 7     for(; ch>'9'||ch<'0'; ) ch=getchar();
 8     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
 9 }
10 
11 int Presist()
12 {
13 //    freopen("cubicp.in","r",stdin);
14     freopen("cubicp.out","w",stdout);
15     LL t,tmp; read(t);
16     for(LL p; t--; )
17     {
18         read(p);bool flag=0;
19         for(int y=1; y<=1e6+5; ++y)
20         {
21             tmp=3ll*y*y+3ll*y+1;
22             if(tmp==p) { flag=1;break; }
23             else if(tmp>p) break;
24         }
25         if(flag) puts("YES");
26         else puts("NO");
27     }
28     return 0;
29 }
30 
31 int Aptal=Presist();
32 int main(int argc,char**argv){;} 
AC

T3 猜数字(number)

Time Limit:1000ms   Memory Limit:128MB

题目描述

    LYK在玩猜数字游戏。

    总共有n个互不相同的正整数,LYK每次猜一段区间的最小值。形如[li,ri]这段区间的数字的最小值一定等于xi。

    我们总能构造出一种方案使得LYK满意。直到…… LYK自己猜的就是矛盾的!

    例如LYK猜[1,3]的最小值是2,[1,4]的最小值是3,这显然就是矛盾的。

    你需要告诉LYK,它第几次猜数字开始就已经矛盾了。

输入格式(number.in)

    第一行两个数n和T,表示有n个数字,LYK猜了T次。
    接下来T行,每行三个数分别表示li,ri和xi。

输出格式(number.out)

输出一个数表示第几次开始出现矛盾,如果一直没出现矛盾输出T+1。

输入样例

20 4

1 10 7

5 19 7

3 12 8

1 20 1

输出样例

3

数据范围

对于50%的数据n<=8,T<=10。

对于80%的数据n<=1000,T<=1000。

对于100%的数据1<=n,T<=1000000,1<=li<=ri<=n,1<=xi<=n(但并不保证一开始的所有数都是1~n的)。

二分不可行的最早次数,从大到小枚举x,

对于一段区间,如果被>x的数覆盖过,则不可行,

判断比xi大的区间的并集是否完全覆盖当前区间,xi相等时,更新区间的交

可以用并查集,将确定最小值的区间放到一个并查集里,

 1 #include <algorithm>
 2 #include <cstdio>
 3 
 4 #define min(a,b) (a<b?a:b)
 5 #define max(a,b) (a>b?a:b)
 6 
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>'9'||ch<'0'; ) ch=getchar();
11     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
12 }
13 const int N(1000005);
14 int n,q;
15 struct Node {
16     int l,r,x;
17     bool operator < (const Node&a)const
18     {
19         return x>a.x;
20     }
21 }g[N],tmp[N];
22 
23 int L,R,Mid,ans;
24 int fa[N],lmin,lmax,rmin,rmax;
25 int find(int x)
26 {
27     return fa[x]==x ?x :fa[x]=find(fa[x]);
28 }
29 inline bool check(int t)
30 {
31     for(int i=1; i<=n+1; ++i) fa[i]=i;
32     for(int i=1; i<=t; ++i) tmp[i]=g[i];
33     std:: sort(tmp+1,tmp+t+1);
34     lmin=lmax=tmp[1].l, rmin=rmax=tmp[1].r;
35     for(int i=2,j,k; i<=t; ++i)
36     {
37         if(tmp[i].x<tmp[i-1].x)
38         {
39             if(find(lmax)>rmin) return 1;
40             j=find(lmin), k=find(rmax+1);
41             for(; j<=rmax; ++j)    fa[find(j)]=k;
42             lmax=lmin=tmp[i].l;
43             rmax=rmin=tmp[i].r;
44         }
45         else
46         {
47             lmin=min(lmin,tmp[i].l);
48             lmax=max(lmax,tmp[i].l);
49             rmin=min(rmin,tmp[i].r);
50             rmax=max(rmax,tmp[i].r);
51             if(lmax>rmin) return 1;
52         }
53     }
54     return find(lmax)>rmin;
55 }
56 
57 int Presist()
58 {
59     freopen("number.in","r",stdin);
60     freopen("number.out","w",stdout);
61     
62     read(n),read(q);
63     for(int i=1; i<=q; ++i)
64         read(g[i].l),read(g[i].r),read(g[i].x);
65     for(R=n; L<=R; )
66     {
67         Mid=L+R>>1;
68         if(check(Mid))
69         {
70             ans=Mid;
71             R=Mid-1;
72         }
73         else L=Mid+1; 
74     }
75     printf("%d
",ans);
76     return 0;
77 }
78 
79 int Aptal=Presist();
80 int main(int argc,char**argv){;}
AC
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7748043.html