Loj一本通刷题记录
夏令营回来后就不知道怎么回事,状态一直不好==
为了让自己不要太颓废,开个坑在noip前把一本通的好题都刷一遍。
如果想要noip拿省一的话,就要开始好好努力了。加油!
为了节省时间,一些比较简单的东西就不再赘述了。
第一部分 基础算法
第 1 章 贪心算法
按右端点排序。
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 #include <cmath>
6 #include <queue>
7 #include <map>
8 #define ll long long
9 #define ull unsigned long long
10 #define out(a) printf("%d ",a)
11 #define writeln printf("\n")
12 const int N=1e5+50;
13 using namespace std;
14 typedef int array[N];
15 int n;
16 int now=0,ans=0;
17 int read()
18 {
19 int s=0,t=1; char c;
20 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
21 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
22 return s*t;
23 }
24 ll readl()
25 {
26 ll s=0,t=1; char c;
27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
29 return s*t;
30 }
31 struct node
32 {
33 int l,r;
34 }a[N];
35 bool cmp(node a,node b)
36 {
37 return a.r==b.r?a.l<b.l:a.r<b.r;
38 }
39 int main()
40 {
41 n=read();
42 for (int i=1;i<=n;i++)
43 a[i].l=read(),a[i].r=read();
44 sort(a+1,a+n+1,cmp);
45 for (int i=1;i<=n;i++)
46 if (now<=a[i].l) now=a[i].r,ans++;
47 out(ans);
48 return 0;
49 }
按右端点排序,在区间的末尾种树,若当前区间前面一部分种了一些,在区间末尾补上足够数量。
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 #include <cmath>
6 #include <queue>
7 #include <map>
8 #define ll long long
9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 const int mod=1e9+7;
13 using namespace std;
14 int n,h;
15 int cnt=0,ans=0;
16 bool vis[N];
17 struct node
18 {
19 int l,r,t;
20 }a[N];
21 int read()
22 {
23 int s=0,t=1; char c;
24 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
25 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
26 return s*t;
27 }
28 ll readl()
29 {
30 ll s=0,t=1; char c;
31 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
32 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
33 return s*t;
34 }
35 bool cmp(node a,node b)
36 {
37 return a.r==b.r?a.l<b.l:a.r<b.r;
38 }
39 int main()
40 {
41 n=read();
42 h=read();
43 for (int i=1;i<=h;i++)
44 a[i].l=read(),a[i].r=read(),a[i].t=read();
45 memset(vis,false,sizeof(vis));
46 sort(a+1,a+h+1,cmp);
47 for (int i=1;i<=h;i++){
48 cnt=0;
49 for (int j=a[i].l;j<=a[i].r;j++)
50 if (vis[j]) cnt++;
51 if (cnt>=a[i].t) continue;
52 for (int j=a[i].r;j>=a[i].l;j--){
53 if (!vis[j]) {
54 vis[j]=true;
55 ans++; cnt++;
56 if (cnt>=a[i].t) break;
57 }
58 }
59 }
60 out(ans);
61 return 0;
62 }
开一个大根堆和一个小根堆维护一下。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 const int mod=1e9+7; 13 using namespace std; 14 int n,x; 15 int a,b; 16 priority_queue<int>q_mi; 17 priority_queue<int,vector<int>,greater<int> >q_mx; 18 int read() 19 { 20 int s=0,t=1; char c; 21 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 22 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 23 return s*t; 24 } 25 ll readl() 26 { 27 ll s=0,t=1; char c; 28 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 29 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 30 return s*t; 31 } 32 int main() 33 { 34 n=read(); 35 for (int i=1;i<=n+1;i++){ 36 x=read(); 37 if (i>n) break; 38 q_mx.push(x),q_mi.push(x); 39 } 40 while (q_mx.size()>1){ 41 a=q_mx.top(); q_mx.pop(); 42 b=q_mx.top(); q_mx.pop(); 43 q_mx.push(a*b+1); 44 } 45 while (q_mi.size()>1){ 46 a=q_mi.top(); q_mi.pop(); 47 b=q_mi.top(); q_mi.pop(); 48 q_mi.push(a*b+1); 49 } 50 out(q_mx.top()-q_mi.top()); 51 return 0; 52 }
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 const int mod=1e9+7; 13 using namespace std; 14 int n,m,x; 15 int sum=0,ans=0; 16 int read() 17 { 18 int s=0,t=1; char c; 19 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 20 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 21 return s*t; 22 } 23 ll readl() 24 { 25 ll s=0,t=1; char c; 26 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 27 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 28 return s*t; 29 } 30 int main() 31 { 32 n=read(); m=read(); sum=0; ans=1; 33 for (int i=1;i<=n;i++){ 34 x=read(); 35 if (sum+x>m) ans++,sum=x; 36 else sum+=x; 37 } 38 out(ans); 39 return 0; 40 }
经典题。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int mod=1e9+7; 13 using namespace std; 14 int n,m,x; 15 int now=0,ans=0; 16 struct node 17 { 18 int l,r; 19 }a[N]; 20 int read() 21 { 22 int s=0,t=1; char c; 23 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 24 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 25 return s*t; 26 } 27 ll readl() 28 { 29 ll s=0,t=1; char c; 30 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 31 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 32 return s*t; 33 } 34 bool cmp(node a,node b) 35 { 36 return a.r<b.r; 37 } 38 int main() 39 { 40 n=read(); 41 for (int i=1;i<=n;i++) 42 a[i].l=read(),a[i].r=read(); 43 sort(a+1,a+n+1,cmp); 44 ans=1; now=a[1].r; 45 for (int i=2;i<=n;i++) 46 if (a[i].l>=now) now=a[i].r,ans++; 47 out(ans); 48 return 0; 49 }
显然每个时刻只能写至多一个作业,那么我们枚举时间,将符合时间限制的作业放到一个大根堆里维护并选价值最大的那个出堆并计算答案,注意时间要倒着枚举否则一些时间限制到了的作业也会被重复计算,还有要注意元素是否会重复入队。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int mod=1e9+7; 13 using namespace std; 14 int n; 15 int mx; 16 int now=1; 17 int ans=0; 18 bool vis[N]; 19 priority_queue<int>q; 20 struct node 21 { 22 int x,y; 23 }a[N]; 24 int read() 25 { 26 int s=0,t=1; char c; 27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 29 return s*t; 30 } 31 ll readl() 32 { 33 ll s=0,t=1; char c; 34 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 35 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 36 return s*t; 37 } 38 bool cmp(node a,node b) 39 { 40 return a.x>b.x; 41 } 42 int main() 43 { 44 n=read(); 45 memset(vis,false,sizeof(vis)); 46 for (int i=1;i<=n;i++) 47 a[i].x=read(),a[i].y=read(),mx=max(mx,a[i].x); 48 sort(a+1,a+n+1,cmp); now=1; 49 for (int i=mx;i;i--){ 50 for (int j=now;j<=n;j++) 51 if (a[j].x>=i&&!vis[j]) q.push(a[j].y),vis[j]=true; 52 else { 53 now=j; break; 54 } 55 if (!q.empty()) ans+=q.top(),q.pop(); 56 } 57 out(ans); 58 return 0; 59 }
这题思路有点奇妙,想不出来于是翻了题解。。
我们不妨假设他最远走到第i个位置,那么走路的花费就确定了,显然他不会走回头路,否则就不是最优解。
那么我们考虑剩下的时间能钓多少鱼,用一个堆维护一下1到i的最优值就行了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 const int mod=1e9+7; 13 using namespace std; 14 int n,h,ho; 15 int num[N],t[N],d[N]; 16 int sum=0,ans; 17 struct node 18 { 19 int num,id; 20 bool operator<(node a)const{ 21 return a.num>num; 22 } 23 }p; 24 priority_queue<node>q; 25 int read() 26 { 27 int s=0,t=1; char c; 28 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 29 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 30 return s*t; 31 } 32 ll readl() 33 { 34 ll s=0,t=1; char c; 35 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 36 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 37 return s*t; 38 } 39 int main() 40 { 41 n=read(),h=read(); h*=12; ho=h; 42 for (int i=1;i<=n;i++) 43 num[i]=read(); 44 for (int i=1;i<=n;i++) 45 d[i]=read(); 46 for (int i=1;i<n;i++) 47 t[i]=read(),t[i]+=t[i-1]; 48 ans=-23333333; 49 for (int i=1;i<=n;i++){ 50 h=ho; h-=t[i-1]; sum=0; 51 //out(h); writeln; 52 while (!q.empty()) q.pop(); 53 for (int j=1;j<=i;j++) 54 q.push((node){num[j],j}); 55 for (int j=1;j<=h;j++){ 56 p=q.top(); 57 if (p.num>0) { 58 sum+=p.num; 59 p.num-=d[p.id]; 60 } 61 else p.num=0; 62 q.pop(); 63 q.push(p); 64 } 65 ans=max(ans,sum); 66 } 67 out(ans); 68 return 0; 69 }
第 2 章 二分与三分
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #include <stack> 9 #define ll long long 10 #define out(a) printf("%d",a) 11 #define writeln printf("\n") 12 using namespace std; 13 const int N=1e5+50; 14 int n,m; 15 int l,r,mid; 16 int a[N]; 17 int read() 18 { 19 int s=0,t=1; char c; 20 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 21 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 22 return s*t; 23 } 24 ll readl() 25 { 26 ll s=0,t=1; char c; 27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 29 return s*t; 30 } 31 bool check(int x) 32 { 33 int now=a[1],cnt=0,num=0; 34 for (int i=2;i<=n;i++){ 35 if (a[i]-now>=x) now=a[i],num++; 36 else cnt++; 37 if (num+1==m) break; 38 } 39 if (cnt+m>n) return false; 40 return true; 41 } 42 int main() 43 { 44 n=read(),m=read(); 45 for (int i=1;i<=n;i++) 46 a[i]=read(); 47 sort(a+1,a+n+1); 48 l=1; r=a[n]-a[1]; 49 while (l<=r){ 50 mid=(l+r)>>1; 51 if (check(mid)) l=mid+1; 52 else r=mid-1; 53 //out(mid); writeln; 54 } 55 out(r); 56 return 0; 57 }
抱歉!NOIP后有些弃疗了,now i am back! 1.26 21:41
给你几个点,单位时间内每个点都向四周扩散,问最快多久连到一块。
没思路,看题解。
如题,二分一下答案,然后很显然每个时刻对于两个点都相向扩散,所以判断条件是两倍的时间≥距离,就可以连一块。
暴力枚举俩点,如果在时间内能相连就用并查集并一块,最后看一下是不是所有点都是同个祖先。
注意距离是双向的!
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d ",a) 10 #define ln printf("\n") 11 const int N=1e5+5; 12 const int MOD=1e9+7; 13 using namespace std; 14 int n; 15 int x[N],y[N]; 16 int dis[150][150]; 17 int pre[N]; 18 int l,r,mid; 19 int read() 20 { 21 int s=0,t=1; char c=getchar(); 22 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 23 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 24 return s*t; 25 } 26 ll readl() 27 { 28 ll s=0,t=1; char c=getchar(); 29 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 30 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 31 return s*t; 32 } 33 int find(int x) 34 { 35 return pre[x]==x?x:pre[x]=find(pre[x]); 36 } 37 void merge(int x,int y) 38 { 39 int fx,fy; 40 fx=find(x); fy=find(y); 41 if (fx!=fy) pre[fx]=fy; 42 } 43 bool check(int x) 44 { 45 int num=0; 46 for (int i=1;i<=n;i++) 47 pre[i]=i; 48 for (int i=1;i<n;i++) 49 for (int j=i+1;j<=n;j++) 50 if (dis[i][j]<=(x<<1)) merge(i,j); 51 for (int i=1;i<=n;i++) 52 if (pre[i]==i) num++; 53 return num==1; 54 } 55 int main() 56 { 57 n=read(); 58 for (int i=1;i<=n;i++) 59 x[i]=read(),y[i]=read(); 60 for (int i=1;i<n;i++) 61 for (int j=i+1;j<=n;j++) 62 dis[i][j]=dis[j][i]=abs(x[i]-x[j])+abs(y[i]-y[j]); 63 l=0; r=1e9; 64 while (l<=r){ 65 mid=(l+r)>>1; 66 if (check(mid)) r=mid-1; 67 else l=mid+1; 68 } 69 out(l); 70 return 0; 71 }
第二部分 字符串算法
第 1 章 哈希和哈希表
讲道理很多哈希题写个map就能解决了=v=
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int MOD1=1e9+7; 13 const int MOD2=19260817; 14 using namespace std; 15 int len1,len2; 16 int num=0; 17 int base; 18 char s1[N],s2[N]; 19 ll Hash[N]; 20 ll pows[N]; 21 int ans=0; 22 int read() 23 { 24 int s=0,t=1; char c; 25 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 26 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 27 return s*t; 28 } 29 ll readl() 30 { 31 ll s=0,t=1; char c; 32 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 33 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 34 return s*t; 35 } 36 ll get(int l,int r) 37 { 38 return (Hash[r]-(ll)Hash[l-1]*pows[r-l+1]%MOD1+MOD1)%MOD1; 39 } 40 void hashs(char s[]) 41 { 42 ll res; char c; 43 c='A'; 44 for (int i=0;i<len1;i++) 45 Hash[i]=(Hash[i-1]*base+s[i]-c+1)%MOD1; 46 } 47 ll hash2(char s[]) 48 { 49 ll res=0; char c; 50 c='A'; 51 for (int i=0;i<len2;i++) 52 res=(res*base+s[i]-c+1)%MOD1; 53 return res; 54 } 55 int main() 56 { 57 scanf("%s",s1); 58 scanf("%s",s2); 59 base=131; pows[0]=1; len1=strlen(s1); len2=strlen(s2); 60 for (int i=1;i<=len2;i++) 61 pows[i]=pows[i-1]*base%MOD1; 62 hashs(s1); 63 num=hash2(s2); 64 for (int i=0;i<=len1-len2;i++) 65 if (get(i,i+len2-1)==num) ans++; 66 out(ans); 67 return 0; 68 }
偷懒写了个map。。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int MOD1=1e9+7; 13 const int MOD2=19260817; 14 using namespace std; 15 map<string,int>cnt; 16 int n,len1,len2; 17 int num=0; 18 int base; 19 char s1[N],s2[N]; 20 ll Hash[N]; 21 ll pows[N]; 22 int ans=0; 23 int read() 24 { 25 int s=0,t=1; char c; 26 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 27 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 28 return s*t; 29 } 30 ll readl() 31 { 32 ll s=0,t=1; char c; 33 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 34 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 35 return s*t; 36 } 37 int main() 38 { 39 n=read(); 40 for (int i=1;i<=n;i++){ 41 scanf("%s",s1); gets(s2); 42 if (s1[0]=='a') cnt[s2]++; 43 else { 44 if (cnt[s2]>0) puts("yes"); 45 else puts("no"); 46 } 47 } 48 return 0; 49 }
#10035. 「一本通 2.1 练习 1」Power Strings
枚举下每段的长度,显然要么长度小于等于len/2,要么等于len。
然后算出每段hash值判断取最小即可。
其实没必要用memset,用了反而会T掉QAQ
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d ",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int MOD=1e9+7; 13 const int base=131; 14 using namespace std; 15 int len,mx,ans; 16 ll Hash[N],Pow[N],last,num; 17 char s[N]; 18 bool flag,f; 19 int read() 20 { 21 int s=0,t=1; char c; 22 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 23 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 24 return s*t; 25 } 26 ll readl() 27 { 28 ll s=0,t=1; char c; 29 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 30 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 31 return s*t; 32 } 33 ll get(int l,int r) 34 { 35 return (Hash[r]-(ll)Hash[l-1]*Pow[r-l+1]%MOD+MOD)%MOD; 36 } 37 void hashs(char s[]) 38 { 39 for (int i=0;i<len;i++) 40 Hash[i]=(ll)(Hash[i-1]*base+s[i]-'A'+1)%MOD; 41 } 42 int main() 43 { 44 mx=0; Pow[0]=1; 45 while (~scanf("%s",s)){ 46 //memset(Hash,0,sizeof(Hash)); 47 if (s[0]=='.') break; 48 len=strlen(s); 49 if ((len>>1)>mx){ 50 for (int i=mx+1;i<=(len>>1);i++) 51 Pow[i]=(ll)Pow[i-1]*base%MOD; 52 mx=len>>1; 53 } 54 hashs(s); f=false; last=num=0; 55 for (int i=1;i<=(len>>1);i++){ 56 if (len%i==0){ 57 flag=true; 58 for (int j=0;j<len-i+1;j+=i){ 59 num=get(j,j+i-1); 60 if (j==0){ 61 last=num; 62 continue; 63 } 64 if (num!=last) { 65 flag=false; 66 break; 67 } 68 } 69 if (flag) { 70 ans=i,f=true; 71 break; 72 } 73 } 74 } 75 if (f) out(len/ans); 76 else out(1); 77 writeln; 78 } 79 return 0; 80 } 81
#10036. 「一本通 2.1 练习 2」Seek the Name, Seek the Fame
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d ",a) 10 #define writeln printf("\n") 11 const int N=4e5+50; 12 const int MOD=1e9+7; 13 const int base=233; 14 using namespace std; 15 int len,mx,tot=0; 16 char s[N]; 17 ll Hash[N],Pow[N]; 18 int ans[N]; 19 int read() 20 { 21 int s=0,t=1; char c; 22 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 23 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 24 return s*t; 25 } 26 ll readl() 27 { 28 ll s=0,t=1; char c; 29 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 30 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 31 return s*t; 32 } 33 ll get(int l,int r) 34 { 35 return (Hash[r]-(ll)Hash[l-1]*Pow[r-l+1]%MOD+MOD)%MOD; 36 } 37 void hashs(char s[]) 38 { 39 for (int i=0;i<len;i++) 40 Hash[i]=(ll)(Hash[i-1]*base+s[i])%MOD; 41 } 42 int main() 43 { 44 mx=0; Pow[0]=1; 45 while (~scanf("%s",s)){ 46 len=strlen(s); tot=0; 47 if (len>mx){ 48 for (int i=mx+1;i<=len;i++) 49 Pow[i]=(ll)Pow[i-1]*base%MOD; 50 mx=len; 51 } 52 hashs(s); 53 for (int i=0;i<len;i++) 54 if (get(0,i)==get(len-i-1,len-1)) ans[++tot]=i+1; 55 for (int i=1;i<=tot;i++) 56 out(ans[i]); 57 writeln; 58 } 59 return 0; 60 }
枚举添加字符用hash判一下前后两段是否相同。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d ",a) 10 #define writeln printf("\n") 11 const int N=2e6+50; 12 const int MOD=1e9+7; 13 const int base=233; 14 using namespace std; 15 char s[N]; 16 int n,len,id; 17 int num,ans,cnt=0; 18 bool f,flag; 19 ll Hash[N],Pow[N]; 20 int read() 21 { 22 int s=0,t=1; char c; 23 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 24 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 25 return s*t; 26 } 27 ll readl() 28 { 29 ll s=0,t=1; char c; 30 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 31 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 32 return s*t; 33 } 34 ll get(int l,int r) 35 { 36 if (l<=r) return (Hash[r]-(ll)Hash[l-1]*Pow[r-l+1]%MOD+MOD)%MOD; 37 else return 0; 38 } 39 ll find(int x) 40 { 41 ll y1=0,y2=0; 42 if (x<=(n>>1)) y1=(get(0,x-1)*Pow[(n>>1)-x]%MOD+get(x+1,n>>1))%MOD,y2=get((n>>1)+1,n-1); 43 else y1=get(0,(n>>1)-1),y2=(get((n>>1),x-1)*Pow[n-x-1]%MOD+get(x+1,n-1))%MOD; 44 //out(y1); out(y2); writeln; 45 if (y1==y2) return y1; 46 else return 0; 47 } 48 int main() 49 { 50 n=read(); 51 if (!(n&1)) { 52 puts("NOT POSSIBLE"); 53 return 0; 54 } 55 else { 56 scanf("%s",s); 57 len=strlen(s); f=flag=false; 58 Pow[0]=1; 59 for (int i=1;i<=len;i++) 60 Pow[i]=Pow[i-1]*base%MOD; 61 for (int i=0;i<len;i++) 62 Hash[i]=(Hash[i-1]*base+s[i])%MOD; 63 for (int i=0;i<len;i++){ 64 num=find(i); 65 if (num) { 66 //out(233); writeln; 67 if (!f) ans=num,id=i; 68 else if (ans!=num) { 69 flag=true; break; 70 } 71 f=true; 72 } 73 } 74 if (f) { 75 if (flag) puts("NOT UNIQUE"); 76 else { 77 for (int i=0;i<len;i++){ 78 if (i!=id) putchar(s[i]),cnt++; 79 if (cnt>=(n>>1)) break; 80 } 81 } 82 } 83 else puts("NOT POSSIBLE"); 84 } 85 return 0; 86 } 87 88
#10038 「一本通 2.1 练习 4」A Horrible Poem
10035那题的升级版,n≤5e5,而且是询问区间的答案.
BZOJ 2795: [Poi2012]A Horrible Poem
正反求一波hash值枚举长度然后把hash值扔到map里算一下就好了,loj上wa+mle水了七十多分,洛谷水了tle90分,后来改了个双hash还是wa,找个时间来调吧,flag++。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d ",a) 10 #define writeln printf("\n") 11 const int N=2e5+50; 12 const int MOD=1e9+7; 13 const int mod=1e9+9; 14 const int base=2333; 15 using namespace std; 16 int n; 17 int a[N],b[N]; 18 int num,num1,num2,num3,num4,l,ans,tot; 19 ll Hash1[N],Hash2[N],Hashs1[N],Hashs2[N],Pow[N],Pows[N]; 20 map<int,int>cnt; 21 map<int,int>cnt2; 22 int read() 23 { 24 int s=0,t=1; char c; 25 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 26 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 27 return s*t; 28 } 29 ll readl() 30 { 31 ll s=0,t=1; char c; 32 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 33 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 34 return s*t; 35 } 36 ll get(int l,int r,int x) 37 { 38 if (x==1) return (Hash1[r]-(ll)Hash1[l-1]*Pow[r-l+1]%MOD+MOD)%MOD; 39 return (Hash2[l]-(ll)Hash2[r+1]*Pow[r-l+1]%MOD+MOD)%MOD; 40 } 41 ll get2(int l,int r,int x) 42 { 43 if (x==1) return (Hashs1[r]-(ll)Hashs1[l-1]*Pows[r-l+1]%mod+mod)%mod; 44 return (Hashs2[l]-(ll)Hashs2[r+1]*Pows[r-l+1]%mod+mod)%mod; 45 } 46 void hash1() 47 { 48 for (int i=1;i<=n;i++){ 49 Hash1[i]=(Hash1[i-1]*base+a[i])%MOD; 50 Hashs1[i]=(Hashs1[i-1]*base+a[i])%mod; 51 } 52 } 53 void hash2() 54 { 55 for (int i=n;i;i--){ 56 Hash2[i]=(Hash2[i+1]*base+a[i])%MOD; 57 Hashs2[i]=(Hashs2[i-1]*base+a[i])%mod; 58 } 59 } 60 int main() 61 { 62 // freopen("beads.in","r",stdin); 63 // freopen("beads.out","w",stdout); 64 n=read(); ans=-23333333; 65 for (int i=1;i<=n;i++) 66 a[i]=read(); 67 hash1(); hash2(); Pow[0]=1; 68 for (int i=1;i<=n;i++){ 69 Pow[i]=Pow[i-1]*base%MOD; 70 Pows[i]=Pows[i-1]*base%mod; 71 } 72 for (int i=1;i<=n;i++){ 73 num=0; 74 if (n/i<ans) break; 75 for (int j=1;j<=n;j+=i){ 76 if (j+(i-1)>n) break; 77 num1=get(j,j+(i-1),1); num2=get(j,j+(i-1),2); 78 num3=get(j,j+(i-1),1); num4=get(j,j+(i-1),2); 79 if ((!cnt[num1]&&!cnt[num2])||(!cnt2[num3]&&!cnt2[num4])) 80 num++,cnt[num1]++,cnt[num2]++,cnt2[num3]++,cnt2[num4]++; 81 } 82 // if (i==199) out(num); 83 if (num==ans) b[++tot]=i; 84 else if (num>ans) { 85 ans=num; 86 tot=0; 87 b[++tot]=i; 88 } 89 } 90 out(ans); out(tot); writeln; 91 for (int i=1;i<=tot;i++) 92 out(b[i]); 93 }
#10040. 「一本通 2.1 练习 6」Antisymmetry
BZOJ 2084: [Poi2010]Antisymmetry
第 2 章 KMP 算法
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=5e5+50; 12 using namespace std; 13 int len1,len2; 14 int nxt[N]; 15 char c,s1[N],s2[N]; 16 int read() 17 { 18 int s=0,t=1; char c; 19 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 20 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 21 return s*t; 22 } 23 ll readl() 24 { 25 ll s=0,t=1; char c; 26 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 27 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 28 return s*t; 29 } 30 void pre() 31 { 32 nxt[1]=0; 33 int j=0; 34 for (int i=1;i<len2;i++){ 35 while (j&&s2[j+1]!=s2[i+1]) j=nxt[j]; 36 if (s2[j+1]==s2[i+1]) j++; 37 nxt[i+1]=j; 38 } 39 } 40 int kmp() 41 { 42 int j=0,ans=0; 43 for (int i=0;i<len1;i++){ 44 while (j&&s2[j+1]!=s1[i+1]) j=nxt[j]; 45 if (s2[j+1]==s1[i+1]) j++; 46 if (j==len2) ans++,j=0; 47 } 48 return ans; 49 } 50 int main() 51 { 52 while (~scanf("%s",s1+1)){ 53 if (s1[1]=='#'&&strlen(s1+1)==1) break; 54 c=getchar(); scanf("%s",s2+1); 55 len1=strlen(s1+1); len2=strlen(s2+1); 56 //cout<<len1<<endl; 57 pre(); 58 out(kmp()); writeln; 59 } 60 return 0; 61 } 62
#10035. 「一本通 2.1 练习 1」Power Strings
不重叠的话就每次从模式串第一位开始找就可以保证。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int len; 15 int nxt[N]; 16 char s[N]; 17 int read() 18 { 19 int s=0,t=1; char c; 20 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 21 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 22 return s*t; 23 } 24 ll readl() 25 { 26 ll s=0,t=1; char c; 27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 29 return s*t; 30 } 31 void pre() 32 { 33 nxt[1]=0; 34 int j=0; 35 for (int i=1;i<len;i++){ 36 while (j&&s[j+1]!=s[i+1]) j=nxt[j]; 37 if (s[i+1]==s[j+1]) j++; 38 nxt[i+1]=j; 39 } 40 } 41 int main() 42 { 43 while (~scanf("%s",s+1)){ 44 if (s[1]=='.') break; 45 len=strlen(s+1); 46 pre(); 47 if (len%(len-nxt[len])==0) out(len/(len-nxt[len])); 48 else out(1); 49 writeln; 50 } 51 return 0; 52 }
#10045. 「一本通 2.2 练习 1」Radio Transmission
BZOJ 1355: [Baltic2009]Radio Transmission
#10049. 「一本通 2.3 例 1」Phone List
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int T,n; 15 int tot; 16 int trie[N][10]; 17 char s[N]; 18 bool flag,f2,f[N]; 19 int read() 20 { 21 int s=0,t=1; char c; 22 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 23 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 24 return s*t; 25 } 26 ll readl() 27 { 28 ll s=0,t=1; char c; 29 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 30 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 31 return s*t; 32 } 33 bool insert(char *s) 34 { 35 int u=1; int len=strlen(s); 36 bool flag=false; 37 for (int i=0;i<len;i++){ 38 int c=s[i]-'0'; 39 if (!trie[u][c]) trie[u][c]=++tot; 40 else if (i==len-1) flag=true; 41 u=trie[u][c]; 42 if (f[u]) flag=true; 43 } 44 f[u]=true; 45 return flag; 46 } 47 int main() 48 { 49 50 //freopen("beads.in","r",stdin); 51 // freopen("beads.out","w",stdout); 52 T=read(); 53 while (T--){ 54 n=read(); tot=1; 55 memset(trie,0,sizeof(trie)); 56 memset(f,false,sizeof(f)); f2=false; 57 for (int i=1;i<=n;i++){ 58 scanf("%s",s); 59 if (insert(s)) 60 f2=true; 61 } 62 if (!f2) puts("YES"); 63 else puts("NO"); 64 } 65 return 0; 66 }
#10050. 「一本通 2.3 例 2」The XOR Largest Pair
01trie经典题
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%lld",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int n; 15 int tot; 16 ll ans,x; 17 int trie[N*32][2]; 18 int read() 19 { 20 int s=0,t=1; char c; 21 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 22 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 23 return s*t; 24 } 25 ll readl() 26 { 27 ll s=0,t=1; char c; 28 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 29 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 30 return s*t; 31 } 32 void insert(ll x) 33 { 34 int u=1; 35 for (int i=31;i>=0;i--){ 36 int c=((1<<i)&x)>0; 37 if (!trie[u][c]) trie[u][c]=++tot; 38 u=trie[u][c]; 39 } 40 } 41 ll find(ll x) 42 { 43 int u=1; ll res=0; 44 for (int i=31;i>=0;i--){ 45 int c=((1<<i)&x)>0; 46 if (trie[u][1-c]) { 47 u=trie[u][1-c]; res+=(1<<i); 48 continue; 49 } 50 u=trie[u][c]; 51 } 52 return res; 53 } 54 int main() 55 { 56 n=read(); tot=1; 57 ans=-23333333; 58 for (int i=1;i<=n;i++){ 59 x=readl(); insert(x); 60 if (ans<find(x)) ans=find(x); 61 } 62 out(ans); 63 return 0; 64 } 65
#10051. 「一本通 2.3 例 3」Nikitosh 和异或
BZOJ 4260: Codechef REBXOR(01trie+思维)
#10052. 「一本通 2.3 练习 1」Immediate Decodability
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e6+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int cnt=0,tot=1; 15 char s[N]; 16 bool flag,f[N]; 17 int trie[N][10]; 18 int read() 19 { 20 int s=0,t=1; char c; 21 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 22 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 23 return s*t; 24 } 25 ll readl() 26 { 27 ll s=0,t=1; char c; 28 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 29 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 30 return s*t; 31 } 32 bool insert(char *s) 33 { 34 int u=1; int len=strlen(s); 35 bool ff=false; 36 for (int i=0;i<len;i++){ 37 int c=s[i]-'0'; 38 if (!trie[u][c]) trie[u][c]=++tot; 39 else if (i==len-1) ff=true; 40 u=trie[u][c]; 41 if (f[u]) ff=true; 42 } 43 f[u]=true; 44 return ff; 45 } 46 int main() 47 { 48 flag=false; 49 while (~scanf("%s",s)){ 50 if (s[0]=='9'&&strlen(s)==1) { 51 if (flag) printf("%s %d %s\n","Set",++cnt,"is not immediately decodable"); 52 else printf("%s %d %s\n","Set",++cnt,"is immediately decodable"); 53 memset(f,false,sizeof(f)); 54 memset(trie,0,sizeof(trie)); flag=false; tot=1; 55 } 56 else if (insert(s)) flag=true; 57 } 58 return 0; 59 } 60
#10056. 「一本通 2.3 练习 5」The XOR-longest Path
BZOJ 1954: Pku3764 The xor-longest Path(01trie)
第三部分 图论
第 1 章 最小生成树
建多一个点0表示发电站,然后其他点往他连边,跑一遍kruskal就没了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define ln printf("\n") 11 const int N=1e5+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int n; 15 int v,p,tot=0; 16 int pre[N]; 17 int ans=0; 18 struct node 19 { 20 int x,y,cost; 21 }edge[N]; 22 int read() 23 { 24 int s=0,t=1; char c; 25 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 26 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 27 return s*t; 28 } 29 ll readl() 30 { 31 ll s=0,t=1; char c; 32 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 33 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 34 return s*t; 35 } 36 void add(int x,int y,int z) 37 { 38 edge[++tot].x=x; 39 edge[tot].y=y; 40 edge[tot].cost=z; 41 } 42 int find(int x) 43 { 44 if (pre[x]==x) return x; 45 else return pre[x]=find(pre[x]); 46 } 47 void Kruskal() 48 { 49 int x,y; 50 for (int i=1;i<=tot;i++){ 51 x=find(edge[i].x); y=find(edge[i].y); 52 if (x!=y){ 53 pre[x]=y; 54 ans+=edge[i].cost; 55 } 56 } 57 } 58 bool cmp(node a,node b) 59 { 60 return a.cost<b.cost; 61 } 62 int main() 63 { 64 n=read(); 65 for (int i=1;i<=n;i++) 66 v=read(),add(0,i,v),add(i,0,v),pre[i]=i; 67 for (int i=1;i<=n;i++) 68 for (int j=1;j<=n;j++) 69 p=read(),add(i,j,p); 70 sort(edge+1,edge+tot+1,cmp); 71 Kruskal(); 72 out(ans); 73 return 0; 74 }
第 2 章 最短路
在加权无向图上求出一条从 1号结点到 N号结点的路径,使路径上第 K+1大的边权尽量小。
看了题解。。。
二分答案,把权值大于mid的边权设为1,否则设为0,跑1到n的最短路.
如果dis[n]>k,那么mid太小,向上缩小区间,否则反之.
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define ln printf("\n") 11 const int N=1e5+50; 12 const int MOD=1e9+7; 13 using namespace std; 14 int n,m,k; 15 int x,y,z; 16 int l,r,mid; 17 int head[N],dis[N]; 18 int tot=0; 19 bool vis[N],flag; 20 struct node 21 { 22 int to,cost,nxt; 23 }edge[N]; 24 int read() 25 { 26 int s=0,t=1; char c; 27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 29 return s*t; 30 } 31 ll readl() 32 { 33 ll s=0,t=1; char c; 34 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 35 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 36 return s*t; 37 } 38 void add(int x,int y,int z) 39 { 40 edge[++tot].to=y; 41 edge[tot].cost=z; 42 edge[tot].nxt=head[x]; 43 head[x]=tot; 44 } 45 struct dist 46 { 47 int id,h; 48 bool operator<(const dist&a)const{ 49 return a.h<h; 50 } 51 }; 52 priority_queue<dist>q; 53 void Dijkstra(int v) 54 { 55 int x,y,z; 56 memset(dis,127,sizeof(dis)); 57 memset(vis,false,sizeof(vis)); 58 dist p; dis[1]=0; 59 p.id=1; p.h=0; 60 q.push(p); 61 while (!q.empty()){ 62 p=q.top(); q.pop(); 63 x=p.id; 64 if (!vis[x]){ 65 vis[x]=true; 66 for (int i=head[x];i;i=edge[i].nxt){ 67 y=edge[i].to; z=edge[i].cost; 68 if (dis[y]>dis[x]+(z<=v?0:1)){ 69 dis[y]=dis[x]+(z<=v?0:1); 70 p.id=y; p.h=dis[y]; 71 q.push(p); 72 } 73 } 74 } 75 } 76 } 77 bool check() 78 { 79 return dis[n]>k?false:true; 80 } 81 int main() 82 { 83 n=read(),m=read(),k=read(); l=0; flag=false; 84 for (int i=1;i<=m;i++) 85 x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z),r+=z; 86 while (l<=r){ 87 mid=(l+r)>>1; 88 Dijkstra(mid); 89 if (dis[n]<=1000) flag=true; 90 if (!check()) l=mid+1; 91 else r=mid-1; 92 } 93 if (flag) out(l); 94 else puts("-1"); 95 return 0; 96 }
从x和其他各点为起点跑最短路,加起来找个最大就行了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define ln printf("\n") 11 #define clear(a,b) memset(a,b,sizeof(a)) 12 const int N=1e5+50; 13 const int MOD=1e9+7; 14 using namespace std; 15 int n,m,s; 16 int x,y,z,tot=0; 17 int dis[N],a[N]; 18 int head[N]; 19 bool vis[N]; 20 int ans=-23333333; 21 struct node 22 { 23 int to,nxt,cost; 24 }edge[N]; 25 struct dist 26 { 27 int h,id; 28 bool operator<(const dist&a)const{ 29 return a.h<h; 30 } 31 }; 32 int read() 33 { 34 int s=0,t=1; char c; 35 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 36 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 37 return s*t; 38 } 39 ll readl() 40 { 41 ll s=0,t=1; char c; 42 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 43 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 44 return s*t; 45 } 46 void add(int x,int y,int z) 47 { 48 edge[++tot].to=y; 49 edge[tot].cost=z; 50 edge[tot].nxt=head[x]; 51 head[x]=tot; 52 } 53 priority_queue<dist>q; 54 void Dijkstra(int s) 55 { 56 clear(dis,127); clear(vis,false); 57 dis[s]=0; 58 dist p; 59 p.h=0; p.id=s; 60 q.push(p); 61 while (!q.empty()){ 62 p=q.top(); q.pop(); 63 x=p.id; 64 if (!vis[x]){ 65 vis[x]=true; 66 for (int i=head[x];i;i=edge[i].nxt){ 67 y=edge[i].to; z=edge[i].cost; 68 if (dis[y]>dis[x]+z){ 69 dis[y]=dis[x]+z; 70 p.h=dis[y]; p.id=y; 71 q.push(p); 72 } 73 } 74 } 75 } 76 } 77 int main() 78 { 79 n=read(),m=read(),s=read(); 80 for (int i=1;i<=m;i++){ 81 x=read(),y=read(),z=read(); 82 add(x,y,z); 83 } 84 Dijkstra(s); 85 for (int i=1;i<=n;i++) 86 a[i]=dis[i]; 87 for (int i=1;i<=n;i++) 88 if (i!=s){ 89 Dijkstra(i); 90 ans=max(ans,a[i]+dis[s]); 91 } 92 out(ans); 93 return 0; 94 }