11.12 刷题笔记
11.12 刷题笔记
本来是可以刷题的,但是因为我昨晚在吃完饭回来之后颓了一小会
教练认为我们一点也不累,所以继续考了.....
但是我改完题了,晚上又写了两道。。
CF258D
思路清奇的期望线性性好题!!
说一句话就明白了,逆序对个数的期望就等于每一对数是否能成为逆序对概率加和
设\(dp_{i,j}\)表示\(i\)比\(j\)大的概率,那么在一开始的序列上就可以直接处理出这个数组
如果交换\(x,y\),首先可以知道要么是\(x \lt y\)要么是\(x \gt y\)
那交换的话\(dp_{x,y}=dp_{y,x}=0.5\)
\(dp_{t,x}=dp_{t,y}=\frac{dp_{t,x}+dp_{t,y}}{2}\)
\(dp_{x,t}=dp_{y,t}=\frac{dp_{x,t}+dp_{y,t}}{2}\)
用\(dp\)数组表示了大小关系,还要满足位置关系
满足\(x\)在\(y\)前面就行了
code
#include<bits/stdc++.h>
using namespace std;
#define fxt(i,x,y) for(int i=(x);i<=(y);i++)
#define pyt(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1005;
int n,m,a[N];
double f[N][N],ans;
signed main(){
scanf("%d%d",&n,&m);
fxt(i,1,n)scanf("%d",&a[i]);
fxt(i,1,n)fxt(j,1,n)if(a[i]>a[j])f[i][j]=1;
fxt(i,1,m){
int x,y;
scanf("%d%d",&x,&y);
fxt(j,1,n){
f[j][x]=f[j][y]=(f[j][x]+f[j][y])*0.5;
f[x][j]=f[y][j]=1.0-f[j][x];
}f[x][y]=f[y][x]=0.5;
}
fxt(i,1,n)fxt(j,i+1,n)ans+=f[i][j];
printf("%.10lf",ans);
}
Luogu P1613 跑路
怎么说今天被一道小绿题难的半死。。
总是记不住倍增的预处理原理
一定是先处理一层在处理一层,这样可以保证都被处理到
所以这个先赋值,直接预处理跑\(floyd\)
code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
inline int read(){
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*f;
}
const int N=55;
const int M=1e4+5;
int n,m;
int to[M*2],nxt[M*2],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
bool vis[N];
int dis[N][N];
int st[N][N][65];
signed main(){
memset(dis,0x3f,sizeof(dis));
n=read();m=read();
fo(i,1,m){
int x=read(),y=read();
add_edg(x,y);dis[x][y]=1;
st[x][y][0]=1;
}
fo(k,1,64)fo(l,1,n)fo(i,1,n)fo(j,1,n)if(st[i][l][k-1]&&st[l][j][k-1])st[i][j][k]=1,dis[i][j]=1;
fo(k,1,n)fo(i,1,n)fo(j,1,n)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
printf("%d",dis[1][n]);
}
Luogu P3509 [POI2010]ZAB-Frog
所以尺取法这么好用呢??
code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
inline int read(){
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*f;
}
const int N=1e6+5;
int n,k,m,a[N];
int st[N][65];
signed main(){
n=read();k=read();m=read();
fo(i,1,n)a[i]=read();
int l=1,r=k+1;
fo(i,1,n){
if(a[r]-a[i]>a[i]-a[l])st[i][0]=r;
else st[i][0]=l;
// cout<<i<<" "<<st[i][0]<<endl;
while(a[i+1]-a[l]>a[r+1]-a[i+1]&&r<n)r++,l++;
}
fo(j,1,60)fo(i,1,n)st[i][j]=st[st[i][j-1]][j-1];
fo(i,1,n){
int now=i,num=0;
fu(j,60,0){
if(num+(1ll<<j)<=m){
now=st[now][j];
num+=(1ll<<j);
}
}
printf("%lld ",now);
}
}
QQ:2953174821

浙公网安备 33010602011771号