【纪中受难记】——C3D5:破题

最后一题不改了,心态炸

 


 

Description

n个天使排成一条直线,某些天使之间需要互相联系,他们之间的通讯可以通过黑白两种通道中的一种;所有通道必须在直线同侧(另一侧是地面);为了保证通讯效率,同种颜色的所有通道之间不能相交。请计算能否建立这种通讯方案。
 

Input

第一行一个数T,表示接下来有T个询问。
对于每个询问:第一行两个数n,m,分别表示有n个天使、需要建立通讯线路的天使有m对;接下来有m行,每行两个数a、b,表示a、b两个天使需要通讯。

Output

对于每个询问,输出一行“sane”表示有可行方案、“non”表示无解。
 

Sample Input

1
7 5
1 3
2 7
3 4
7 4
6 5

Sample Output

sane
 

Data Constraint

对于 20%的数据,1<=n<=50,1<=m<=15
对于 50%的数据,1<=n<=1000,1<=m<=300
对于 100%的数据,1<=n<=5000,1<=m<=1000,1<=T<=10,1<=a<=n,1<=b<=n
数据保证每对(a,b)不重复,且a不等于b
 

Hint

【提示】
当两条线路有一对相同的端点时,这两条线路不相交。
也就是说,对于线路(a,b)和线路(c,d)(a<b且c<d),当且仅当a<c<b<d或者c<a<d<b时这两条线路相交。

这道题就是m^2判断相交线段,然后给图染色即可。

很水。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int read(){
 4     int x=0,f=1;
 5     char c=getchar();
 6     while(!isdigit(c)){
 7         if(c=='-') f=-1;
 8         c=getchar();
 9     }
10     while(isdigit(c)){
11         x=(x<<1)+(x<<3)+(c^48);
12         c=getchar();
13     }
14     return x*f;
15 }
16 int T,n,m;
17 const int N=1010;
18 struct node{
19     int l,r;
20 }h[N];
21 int vis[N];
22 int flag;
23 struct edge{
24     int to,nxt;
25 }e[N<<1];
26 int head[N<<1],cnt;
27 void addedge(int from,int to){
28     e[++cnt]=(edge){to,head[from]};
29     head[from]=cnt;
30 }
31 void dfs(int u,int col){
32     if(flag) return;
33     if(vis[u]){
34         if(vis[u]!=col) flag=1;
35         return;
36     }
37     else vis[u]=col;
38     for(int i=head[u];i;i=e[i].nxt){
39         int v=e[i].to;
40         dfs(v,col^1);
41         if(flag) return;
42     }
43 }
44 int main(){
45     T=read();
46     while(T--){
47 //        t.clear();
48         memset(vis,0,sizeof(vis));
49         memset(head,0,sizeof(head));
50         cnt=0;
51         n=read();m=read();
52         for(int i=1;i<=m;i++){
53             h[i].l=read();
54             h[i].r=read();
55             if(h[i].l>h[i].r) swap(h[i].l,h[i].r);
56         }
57         for(int i=1;i<=m;i++){
58             for(int j=1;j<i;j++){
59                 if((h[i].l<h[j].l&&h[i].r<h[j].r&&h[i].r>h[j].l)||(h[i].l>h[j].l&&h[i].r>h[j].r&&h[i].l<h[j].r)){
60                     addedge(i,j);
61                     addedge(j,i);
62                 }
63             }
64         }
65         flag=0;
66         for(int i=1;i<=m;i++){
67             if(flag) break;
68             if(!vis[i]) dfs(i,2);
69         }
70         if(flag){
71             printf("non\n");
72         }
73         else printf("sane\n");
74     }
75     return 0;
76 }

 


 

Description

因为SJY干的奇怪事情过多,SJY收到了休假的通知,于是他准备在都市间来回旅游。SJY有一辆车子,一开始行驶性能为0,每过1时间行驶性能就会提升1点。每个城市的道路都有性能要求。SJY一共有t时间休息,一开始他位于1号城市(保证1号城市道路要求为0),他希望在n号城市结束旅程。每次穿过一条城市间的路会花费1时间,当然他也可以停留在一个城市不动而花费1时间。当且仅当车子的行驶性能大于等于一个城市,我们才能到达那里。SJY希望知道,旅游的方案模10086后的答案。(只要在某一时刻通过的道路存在一条不相同,就算不同的方案)
 

Input

第一行三个数n,m,t,表示有n个城市m条道路t时间。
第二行n个数,hi表示第i个城市的道路性能要求。
第三到m+2行,每行两个数u,v,表示城市u与城市v之间有一条单向道路连接(可能有重边)。

Output

包括一个数字,表示旅游的方案模10086。
 

Sample Input

5 17 7
0 2 4 5 3 
1 2
2 1
1 3
3 1
1 4
4 1
4 5
5 4
5 3
4 1
2 1
5 3
2 1
2 1
1 2
2 1
1 3

Sample Output

245
 

Data Constraint

对于20%的数据,n<=10,t<=80;
对于50%的数据,n<=30,t<=80;
对于100%的数据,n<=70,m<=1000,t<=100000000,hi<=70。

 

这道题很有趣,发现hi<=70,先暴力打出前70时间的答案,然后多余的时间矩阵快速幂搞定。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int read(){
 4     int x=0,f=1;
 5     char c=getchar();
 6     while(!isdigit(c)){
 7         if(c=='-') f=-1;
 8         c=getchar();
 9     }
10     while(isdigit(c)){
11         x=(x<<1)+(x<<3)+(c^48);
12         c=getchar();
13     }
14     return x*f;
15 }
16 const int mod=10086;
17 typedef long long ll;
18 const int N=100;
19 int n,m,t;
20 int level[N];
21 struct matrix{
22     ll a[N][N];
23     void Empty(){
24         memset(a,0,sizeof(a));
25     }
26     void One(){
27         Empty();
28         for(int i=1;i<=n;i++) a[i][i]=1;
29     }
30     void reset(){
31         Empty();
32     }
33     matrix operator*(matrix b){
34         matrix tmp;
35         tmp.Empty();
36         for(int r=1;r<=n;r++){
37             for(int j=1;j<=n;j++){
38                 for(int k=1;k<=n;k++){
39                     (tmp.a[r][j]+=a[r][k]*b.a[k][j]%mod)%=mod;
40                 }
41             }
42         }
43         return tmp;
44     }
45 }res,ans;
46 void pow(ll p){
47     while(p){
48         if(p&1){
49             ans=ans*res;
50         }
51         res=res*res;
52         p>>=1;
53     }
54 }
55 struct node{
56     int l,r;
57     int maxlevel;
58     bool operator < (const node &x)const{
59         return maxlevel<x.maxlevel;
60     }
61 }h[5010];
62 int cnt;
63 int vis[N][N];
64 ll f[N][N];
65 int main(){
66     n=read();m=read();t=read();
67     for(int i=1;i<=n;i++){
68         level[i]=read();
69     }
70     for(int i=1;i<=m;i++){
71         int x=read(),y=read();
72         if(!vis[x][y]) h[++cnt]=(node){x,y};
73         vis[x][y]++;
74     }
75     f[0][1]=1;
76     for(int i=1;i<=70;i++){
77         for(int j=1;j<=n;j++) f[i][j]=f[i-1][j];
78         for(int j=1;j<=cnt;j++){
79             if(i>=level[h[j].r]) f[i][h[j].r]=(f[i][h[j].r]+f[i-1][h[j].l]*vis[h[j].l][h[j].r])%mod;
80         }
81     }
82     if(t<=70){
83         printf("%lld",f[t][n]);
84         return 0;
85     }
86     res.One();
87     for(int i=1;i<=n;i++){
88         ans.a[1][i]=f[70][i];
89     }
90     for(int i=1;i<=cnt;i++){
91         res.a[h[i].l][h[i].r]=vis[h[i].l][h[i].r];
92     }
93     pow(t-70);
94     printf("%lld",ans.a[1][n]);
95     return 0;
96 }

 

Description

 

Input

第一行一个整数N,表示统计范围是自然数的Fibonacci 表示的前N个数字。

Output

一个数,前N个数字中1的个数。
 

Sample Input

21

Sample Output

10
【样例解释】
前21个数字为110100101100010011010,共有10个1。
 

Data Constraint

30%的数据N≤1000;
50%的数据N≤10^6;
100%的数据N≤10^15。

 

没改,直接上题解吧。

 

大意就是各种细节的计数。

我*……%&¥%……%&%#

posted @ 2019-11-07 20:07  Nelson992770019  阅读(208)  评论(0编辑  收藏  举报