國慶DAY1訓練
阿新 • • 發佈:2019-01-13
J 模擬
題意:移動數字
記錄一下每個數字的位置 然後如果和0的距離為1 則交換
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
}p[1020000];
//pos
int cal(int x,int y){
return abs(p[x].x-p[y].x)+abs(p[x].y-p[y].y);
}
int a[1020000];
int main(){
int n,m;
ios::sync_with_stdio(0);
cin.tie(0);
while(cin>>n>> m&&(n||m)){
int data;
for(int i = 1; i <= n ; i++ ){
for(int j =1 ; j <= n ; j++){
cin>>data;
p[data].x = i;
p[data].y = j;
}
}
while(m--){
int x;
cin>>x;
if(cal(x,0)==1){
swap(p[x],p[0]);
}
}
for(int i = 0 ; i <= n * n - 1; i++ ){
a[(p[i].x-1)*n + p[i].y] = i;
}
for(int i = 1; i <= n * n; i++){
printf("%d%c",a[i],i==n*n?'\n':' ');
}
}
return 0;
}
A
題意:
find such a x
let a^x + b ^ x = 0 mod p ^k
p is prime and odd
conclusion:
if exist t
a^t + b ^ t = 0 mod p ^ k
a^ pt + b ^ pt = 0 mod p^(k+1)
prove:
let c = a^t:
b^t = (p ^ k )* d - a ^ t
c^p + ( (p ^ k ) * d - c) ^ p
後面那個二項式展開 然後化簡一下你會發現可以整除p^(k+1) 的
所以就可以遞推了
first
find such a x which
a^x + b ^x = 0 mod p
we can search x of (1~p-1) ( It’s a brute force) to find whether it is true
if doesn’t exist :
ans=-1
else 遞推到k次
why not to find more
because we know that a^(p-1) = 1 mod p
so it is enough to find 1~p-1
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a,b,p,k;
ll ppow(ll a,ll n){
ll ret = 1;
while(n){
if(n&1) ret = ret*a ;
a = a*a ;
n>>=1;
}
return ret;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
while(cin>>a>>b>>p>>k){
ll temp = a;
ll temp1 = b;
ll ans = 0;
for(ll i = 1; i<=p-1 ;i++){
ll now = (temp + temp1) % p;
if(now==0){
ans=i;
break;
}
temp = temp * a % p;
temp1 = temp1 * b % p;
}
if(ans==0){
printf("-1\n");
}
else{
printf("%lld\n",ppow(p,k-1)*ans);
}
}
return 0;
}
C
期望題
先求出兩個圓相交的概率
設R>=r
固定R 的 位置 分類討論一下r中軸的位置 根據面積公式求一下面積比 算出概率
最後得出期望即可
n個點可以先sort一下
兩兩求一下概率
#include <bits/stdc++.h>
using namespace std;
double r[302000];
int main(){
int n;
double R;
cin>>n>>R;
for(int i=1;i<=n;++i){
cin>>r[i];
}
sort(r+1,r+1+n);
double ans = 0;
double sum = 0;
for(int i = 1 ; i <= n ; i++ ){
ans += sum * r[i]/R;
sum += r[i]/R;
}
printf("%.10lf\n",ans*2);
return 0;
}
H
曼哈頓最小生成樹
優化可以對每個點求8個象限
求最大邊
板子題 板子是求第k條邊
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000001;
const int INF = 0x3f3f3f3f;
struct Point{
int x,y,id;
}p[MAXN];
bool cmp(Point a, Point b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
struct BIT{
int min_val,pos;
void init(){
min_val = INF;
pos = -1;
}
}bit[MAXN];
struct Edge{
int u,v,d;
}edge[MAXN<<2];
bool cmpedge(Edge a, Edge b){
return a.d<b.d;
}
int tot;
int n;
int F[MAXN];
int find(int x){
if(F[x]==-1) return x;
else return F[x]=find(F[x]);
}
void addedge(int u,int v,int d){
edge[tot].u = u;
edge[tot].v = v;
edge[tot++].d = d;
}
int lowbit(int x){
return x&(-x);
}
void update(int i,int val,int pos){
while(i){
if(val<bit[i].min_val){
bit[i].min_val = val;
bit[i].pos = pos;
}
i -= lowbit(i);
}
}
int ask(int i,int m){
int min_val = INF, pos = -1;
while(i<=m){
if(bit[i].min_val<min_val){
min_val = bit[i].min_val;
pos = bit[i].pos;
}
i += lowbit(i);
}
return pos;
}
int dist(Point a, Point b){
return abs(a.x-b.x) + abs(a.y-b.y);
}
void Manhattan_MST(int n,Point p[]){
int a[MAXN],b[MAXN];
tot = 0;
for(int dir = 0; dir<4; dir++){
if(dir==1||dir==3){
for(int i=0;i<n;++i){
swap(p[i].x,p[i].y);
}
}
else if(dir==2){
for(int i=0;i<n;++i){
p[i].x = -p[i].x;
}
}
sort(p,p+n,cmp);
for(int i=0;i<n;++i){
a[i]=b[i]=p[i].y-p[i].x;
}
sort(b,b+n);
int m = unique(b,b+n)-b;
for(int i=1;i<=m;++i){
bit[i].init();
}
for(int i=n-1;i>=0;--i){
int pos = lower_bound(b,b+m,a[i])-b+1;
int ans = ask(pos,m);
if(ans!=-1){
addedge(p[i].id,p[ans].id,dist(p[i],p[ans]));
}
update(pos,p[i].x+p[i].y,i);
}
}
}
int solve(int k){
Manhattan_MST(n,p);
memset(F,-1,sizeof(F));
sort(edge,edge+tot,cmpedge);
for(int i=0;i<tot;++i){
int u = edge[i].u;
int v = edge[i].v;
int t1 = find(u),t2=find(v);
if(t1!=t2){
F[t1]=t2;
k--;
if(k==0) return edge[i].d;
}
}
return 0;
}
int main(){
while(cin>>n&&n){
for(int i=0;i<n;++i){
cin>>p[i].x>>p[i].y;
p[i].id = i;
}
cout<<solve(n-1)<<endl;
}
return 0;
}