由于对Floyd的本质还是不大清楚所以做这个题还是费了点功夫,可以把整个过程反过来,就变成了解锁每个点对当前已有点的影响,其实这样也就相当于一个floyd了,值得注意的是虽然有的点没有解锁,但是是可以参与转移的,只不过累加和的时候不能加上他,为什么可以参加转移呢?因为最开始的那个k循环实际的意义就是将k这个点作为中转点来更新i和j的最短路,k是被解锁的,所以如果i和j通过k转移也是合法的,这样还不会漏掉情况
题解 P1119 【灾后重建】 - Time_Rune 的博客 - 洛谷博客 (luogu.com.cn)
- #include
- using namespace std;
- #define int long long
- //const int mod=1e9+7;
- const int inf=1e18;
- const int N = 2e6+100;
- int n,g[505][505],a[505][505],ans[505],b[505],vis[505];
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- //cout<<(1LL<<19)<
- cin>>n;
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- {
- cin>>a[i][j];
- g[i][j]=a[i][j];
- }
- for(int i=1;i<=n;i++) cin>>b[i],vis[i]=0;
- for(int k=n;k>=1;k--)
- {
- vis[b[k]]=1;
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- {
- g[i][j]=min(g[i][j],g[i][b[k]]+g[b[k]][j]);
- // if(k==2&&i==3&&j==4) cout<
- }
-
- int res=0;
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- {
- //if(k==2) cout<
- if(vis[i]&&vis[j]) res+=g[i][j];
- }
- ans[k]=res;
- }
- for(int i=1;i<=n;i++) cout<
" "; - system("pause");
- return 0;
- }
-
- /*
- 4
- 0 57148 51001 13357
- 71125 0 98369 67226
- 49388 90852 0 66291
- 39573 38165 97007 0
- 2 3 1 4
- */
最关键的是找到合适的x,y,先假设已经找到了,考虑如何输出,设in为在值域里面的数的个数,out为不在的个数,那么只要in==out+1了就可以输出这个区间,最后一段直接输出就可以,一定是满足条件的,然后可以发现前k-1段都是in==out+1,后面那一段in>=out+1,所以总的就是in>=out+k,所以就可以按照这个条件去枚举了,可以双指针也可以二分
Codeforces Round #768 (Div. 2) D(二分答案/双指针) - 知乎 (zhihu.com)
- #include
- using namespace std;
- #define int long long
- //const int mod=1e9+7;
- const int inf=1e18;
- const int N = 2e6+100;
- int t,n,k,a[N],sum[N],tx[N];
- bool check(int l,int r)
- {
- return (2LL*(sum[r]-sum[l-1])-n>=k);
-
- }
- void print(int x,int y)
- {
- int in=0,out=0,l=1,cnt=1;
- for(int i=1;i<=n&&cnt
- {
- if(a[i]>=x&&a[i]<=y) in++;
- else out++;
- if(in>out)
- {
- cout<
" "< - l=i+1;cnt++;in=0,out=0;
- }
- }
- cout<
" "< - }
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- //cout<<(1LL<<19)<
- cin>>t;
- while(t--)
- {
- cin>>n>>k;
- for(int i=0;i<=n;i++) sum[i]=tx[i]=0;
- for(int i=1;i<=n;i++) cin>>a[i],tx[a[i]]++;
- for(int i=1;i<=n;i++)
- sum[i]=sum[i-1]+tx[i];
- int ansl=1,ansr=n;
- for(int i=1,l=1;i<=n;i++)
- {
- while(l<=i&&check(l,i))
- {
-
- if(ansr-ansl>i-l)
- {
- ansr=i,ansl=l;
-
- }
- l++;
- }
- }
- cout<
" "< - print(ansl,ansr);
- }
- system("pause");
- return 0;
- }
P5656 【模板】二元一次不定方程 (exgcd)
求x,y的最小正整数解,一开始看了一个没有代码的题解越算越不对直接emo了
【题解】【P5656-【模板】二元一次不定方程(exgcd)】 - 古明地觉世界第一! - 洛谷博客
- #include
- using namespace std;
- #define int long long
- //const int mod=1e9+7;
- const int inf=1e18;
- const int N = 2e6+100;
- int exgcd(int a,int b,int &x,int &y)
- {
- if(b==0)
- {
- x=1;y=0;
- return a;
- }
- int r=exgcd(b,a%b,x,y);
- int temp=y;
- y=x-(a/b)*y;
- x=temp;
- return r;
- }
- signed main()
- {
- //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- //cout<<(1LL<<19)<
- int t,a,b,c;
- cin>>t;
- while(t--)
- {
- cin>>a>>b>>c;
- int g=__gcd(a,b);
- if(c%g)
- {
- cout<<"-1\n";
- continue;
- }
- int x,y,p=b/g,q=a/g,k;
- exgcd(a,b,x,y);
- x*=c/g;y*=c/g;
- if(x<0) k=ceil((1.0-x)/p),x+=p*k,y-=q*k;
- else if(x>=0) k=(x-1)/p,x-=p*k,y+=q*k;
- //上面的操作都是将x变为最小正整数
- if(y>0)
- {
- int num=(y-1)/q+1;//就是看看y可以减多少次q,但是一开始的y也是一个解所以要加1
- int minx=x;
- int miny=(y-1)%q+1;//这一步我的理解是y可能是q的倍数,为了取余q不等于0所以只要减到y==q就可以了
- int maxx=x+(y-1)/q*p;//y可以减多少次q,x就可以加多少次p
- int maxy=y;
- cout<
" "<" "<" "<" "< - }
- else
- {
- int minx=x;
- int miny=y+q*ceil((1.0-y)/q);
- cout<
" "< - }
- }
- system("pause");
- return 0;
- }
E - Draw a triangle 向量求三角形面积,exgcd
设第三个点的坐标为x3,y3,则可以求出两条向量A(x2-x1,y2-y1),B(x3-x1,y3-y1),然后两个向量叉乘的模的一半就是三角形的面积S=-(y2-y1)*(x3-x1)+(x2-x1)*(y3-y1),设x=x3-x1,y=y3-y1,a=-(y2-y1),b=(x2-x1),那么式子就变成了S=ax+by,然后就是求x,y让S最小,结论是S为gcd(a,b)时是最小的,所以直接扩展欧几里得算就可以,最后exgcd好像不能算负数的系数,所以就先转化成正的,然后求得的x和y再取个反就行
E. Draw a triangle(计算几何+EXGCD)_追随远方的某R的博客-CSDN博客
- #include
- using namespace std;
- #define int long long
- //const int mod=1e9+7;
- const int inf=1e18;
- const int N = 2e6+100;
- int exgcd(int a,int b,int &x,int &y)
- {
- if(b==0)
- {
- x=1;y=0;
- return a;
- }
- int r=exgcd(b,a%b,x,y);
- int temp=y;
- y=x-(a/b)*y;
- x=temp;
- return r;
- }
- signed main()
- {
- //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- //cout<<(1LL<<19)<
- int t;
- cin>>t;
- while(t--)
- {
- int x1,y1,x2,y2,x3,y3;
- cin>>x1>>y1>>x2>>y2;
- int a=-(y2-y1),b=x2-x1;
- int f1=1,f2=1;
- if(a<=0)
- {
- f1=-1;
- a*=f1;
- }
- if(b<=0)
- {
- f2=-1;
- b*=f2;
- }
- exgcd(a,b,x3,y3);
- x3*=f1;y3*=f2;
- x3+=x1;
- y3+=y1;
- cout<
" "< - }
- system("pause");
- return 0;
- }
D-史莱姆的战术训练_并查集
先计算出每一种的粘度然后从大到小排序,可以发现只要从大到小遍历就只要管这个地方访没访问到就可以了,因为后来的一定比不上之前的粘度大,一个一个找的话会很慢,这时候又可以用并查集来辅助跳跃了,这个只要管行之间的跳跃就可以,不然写代码有点太麻烦了,,,
为了更加的优化,列最好是要比行多的,所以如果n>m就交换一下
齐鲁工业大学第四届程序设计竞赛题解_牛客博客 (nowcoder.net)
- #include
- using namespace std;
- #define endl '\n'
- #define int long long
- //const int mod=1e9+7;
- const int inf=1e18;
- const int N = 1e7+100;
- int n,m,p,c,a,b,s[N],col[N],vis[N],ori[N],ans[N];
- int findd(int x){return x==s[x]?x:s[x]=findd(s[x]);}
- struct node
- {
- int x1,y1,x2,y2,co;
- bool operator<(const node &a)const
- {
- return co>a.co;
- }
- }q[N];
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
- cin>>n>>m>>p>>c>>a>>b;
- int flag=0;
- if(n>m) swap(n,m),flag=1;
- for(int i=1;i<=c;i++)
- {
- cin>>col[i];
- ori[col[i]]=i;
- //cout<
- col[i]=a*col[i]+b;
- }
- for(int i=1;i<=p;i++)
- {
- if(flag) cin>>q[i].y1>>q[i].x1>>q[i].y2>>q[i].x2>>q[i].co;
- else cin>>q[i].x1>>q[i].y1>>q[i].x2>>q[i].y2>>q[i].co;
- q[i].co=col[q[i].co];
- }
- sort(q+1,q+p+1);
- for(int i=1;i<=n*m+5;i++) s[i]=i;
- for(int i=1;i<=p;i++)
- {
- int x1=q[i].x1,x2=q[i].x2,y1=q[i].y1,y2=q[i].y2,co=q[i].co;
- if(co<=0) continue;
- for(int j=x1;j<=x2;j++)
- {
- for(int k=findd((j-1)*m+y1);k<=((j-1)*m+y2);k=findd(k+1))
- {
-
- ans[k]=ori[(co-b)/a];
- //cout<
- s[k]=k+1;
- }
- }
- }
- if(flag)
- {
- for(int i=1;i<=m;i++)
- {
- for(int j=1;j<=n;j++) cout<
-1)*m+i]<<" ";//这个地方值得注意一下,交换nm后该如何输出 - cout<
- }
- }
- else
- {
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=m;j++) cout<
-1)*m+j]<<" "; - cout<
- }
- }
- system("pause");
- return 0;
- }
-
相关阅读:
influxdb2如何同时应用多个聚合函数
电磁场与电磁波part1--矢量分析
Python时间序列分析库介绍:statsmodels、tslearn、tssearch、tsfresh
【虹科分享】什么是Redis数据集成(RDI)?
硬实力+软实力!2023功能测试进阶之路!
芯邦'CBM2099E
yolo-目标检测算法简介
代码随想录day52|300. 最长递增子序列674. 最长连续递增序列718. 最长重复子数组
单臂路由 - 实验配置
多线程adsfasdfasdf
-
原文地址:https://blog.csdn.net/weixin_52621204/article/details/127664328