首页 > 其他分享 >2024.6.9

2024.6.9

时间:2024-06-09 17:22:15浏览次数:8  
标签:oo czy 2024.6 int ll 样例 long

2024.6.9 【最后一天!!! 年年今日,灯明如昼。原火不灭,愿人依旧。】

Sunday 五月初四


A. 挖掘机

题目描述
今天,丧尸czy开着挖掘机去上学(……)。但是他发现他的mz满天下,所以一路上他碰到了好多他的mz。一开始他以1km/min的速度(=60km/h……)开着挖掘机前进。他发现他只会在恰好到达某一时刻或者到达某个距离遇到mz。每次遇到mz,czy都会毫不犹豫的把她们顺路捎走(_)。但是他实在是太虚了,以至于当有i个mz时他的速度下降到1/(i+1)。具体说,一开始czy以1km/min速度前进,有1个mz的时候速度变为1/2 km/min,有2个时变为1/3 km/min……以此类推。现在问题来了,给出每个mz在何时出现,请你算出czy到学校要多久。

输入输出格式
输入第一行2个数n,m,分别表示mz数和czy与学校的距离(km)

接下来2到n+1行由字符串与数字构成

Dist x表示在距离达到x km时出现一个mz

Time x表示在时间达到x min时出现一个mz

输出一个整数,表示到达学校的时间。如果不能整除,直接输出整数部分即可。

样例输入

2 20
Time 3
Dist 10

样例输出

47

数据范围
对于30%数据,n,m<=50

对于50%数据,n,m<=2000

对于100%数据,n,m<=200000,x<=10^9,保证输入的数字都是整数

//2024.6.9
//by white_ice
#include<bits/stdc++.h>
#include"fopen.cpp"
using namespace std;
#define itn long long
#define int long long
constexpr int oo = 200005;

itn st[oo],sp[oo];
int top1,top2;

int n,m;

char c[5];

signed main(){
    fre();

    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    cin >> n >> m ;

    for (int x,i=1;i<=n;i++){
        cin >> c;
        cin >> x;
        if (c[0]=='T')
            st[++top1] = x;
        else sp[++top2] = x;
    }

    sp[++top2] =m;
    sort(st+1,st+top1+1);
    sort(sp+1,sp+top2+1);

    double out=0,p=0;
    int cnt=1,ned=1;

    //cout << top1 << top2;

    for (itn i=1;i<=top2;i++){
        while(ned<=top1){
            if (out+cnt*(sp[i]-p)<=st[ned])
                break;
            p += (st[ned]-out)/cnt;
            out=st[ned];
            cnt++;
            ned++;
        }
        out+=cnt*(sp[i]-p);
        p=sp[i];
        cnt++;
    }
    cout << (int)out;

    return 0;
}

贪心加模拟,

就嗯模就行呗


B. 黑红树

题目背景
Mz们在czy的生日送他一个黑红树种子……czy种下种子,结果种子很快就长得飞快,它的枝干伸入空中看不见了……

题目描述
Czy发现黑红树具有一些独特的性质。

1、 这是二叉树,除根节点外每个节点都有红与黑之间的一种颜色。

2、 每个节点的两个儿子节点都被染成恰好一个红色一个黑色。

3、 这棵树你是望不到头的(树的深度可以到无限大)

4、 黑红树上的高度这样定义:h(根节点)=0,h[son]=h[father]+1。

Czy想从树根顺着树往上爬。他有p/q的概率到达红色的儿子节点,有1-p/q的概率到达黑色节点。但是他知道如果自己经过的路径是不平衡的,他会马上摔下来。一条红黑树上的链是不平衡的,当且仅当红色节点与黑色节点的个数之差大于1。

现在他想知道他刚好在高度为h的地方摔下来的概率的精确值a/b,gcd(a,b)=0。那可能很大,所以他只要知道a,b对K取模的结果就可以了。另外,czy对输入数据加密:第i个询问Qi真正大小将是给定的Q减上一个询问的第一个值a%K.

输入输出格式
第一行四个数p,q,T,k,表示走红色节点概率是p/q,以下T组询问,答案对K取模。

接下来T行,每行一个数 Q,表示czy想知道刚好在高度Q掉下来的概率(已加密)

输出T行,每行两个整数,表示要求的概率a/b中a%K和b%K的精确值。如果这个概率就是0或1,直接输出0 0或1 1(中间有空格)。

样例输入1

2 3 2 100	
1
2

样例输入2

2 3 2 20
4
6

样例输出1

0 0
5 9

样例输出2

0 1
0 9

数据范围
对于30%数据,p,q<=5,T<=1000,K<=127,对于任意解密后的Q,有Q<=30

对于60%数据,p,q<=20,T<=100000,K<=65535,对于任意解密后的Q,有Q<=1000

对于100%数据,p,q<=100,T<=1000000, K<=1000000007,对于任意解密后的Q,有Q<=1000000 对于100%数据,有q>p,即0<= p/q<=1

//2024.6.9
//by white_ice
#include<bits/stdc++.h>
//#include"fopen.cpp"
using namespace std;
#define ll long long
constexpr int oo = 1000006;

ll p,q;     ll t,k;
ll h1,h2;   ll s1,s2;
ll h[oo];   ll f[oo];

ll a,b;
ll gcd(ll x,ll y){return (x%y)==0?y:gcd(y,x%y);}

int main(){
    //fre();

    cin >> p >> q >> t >> k;

    // ios::sync_with_stdio(0);
    // cin.tie(0),cout.tie(0);

    h1 = 2*p*(q-p);       h2 = q*q;

    ll l = gcd(h1,h2);

    h1 /= l;              h2 /= l;
    s1 = p*p*2+q*q-2*p*q; s2 = q*q;

    l = gcd(s1,s2);

    s1 /= l;              s2 /= l;

    h[0] = 1;             f[0] = 1;

    for(int i=1;i<=500000;i++)
        h[i] = (h[i-1]*h1) % k,
        f[i] = (f[i-1]*h2) % k;

    ll x;

    while(t--){
        cin >> x;
        x -= a;

        if(x==0||(x&1)){
            cout << "0 0\n";
            a = 0;
            continue;
        }

        else{
            x /= 2;
            a = (h[x-1]*s1)%k;
            b = (f[x-1]*s2)%k;
            cout << a%k << ' ' << b%k << '\n';
        }
    }

    return 0;
}

概率DP,

不会

挺直白的DP,写就完了。


C. 藏宝图

题目背景
Czy爬上黑红树,到达了一个奇怪的地方……

题目描述
Czy发现了一张奇怪的藏宝图。图上有n个点,m条无向边。已经标出了图中两两之间距离dist。但是czy知道,只有当图刚好又是一颗树的时候,这张藏宝图才是真的。如果藏宝图是真的,那么经过点x的边的边权平均数最大的那个x是藏着宝物的地方。请计算这是不是真的藏宝图,如果是真的藏宝之处在哪里。

输入输出格式
输入数据第一行一个数T,表示T组数据。

对于每组数据,第一行一个n,表示藏宝图上的点的个数。

接下来n行,每行n个数,表示两两节点之间的距离。

输出一行或两行。第一行”Yes”或”No”,表示这是不是真的藏宝图。

若是真的藏宝图,第二行再输出一个数,表示哪个点是藏宝之处。

样例输入

2
3
0 7 9
7 0 2
9 2 0
3
0 2 7
2 0 9
7 9 0

样例输出

Yes
1
Yes
3

样例解释:
第一棵树的形状是1--2--3。1、2之间的边权是7,2、3之间是2。

第二棵树的形状是2--1--3。2、1之间的边权是2,1、3之间是7。

数据范围
对于30%数据,n<=50,1<=树上的边的长度<=10^9。

对于50%数据,n<=600。

对于100%数据,1<=n<=2500,除30%小数据外任意0<=dist[i][j]<=10^9,T<=5

//2024.6.9
//by white_ice
#include <bits/stdc++.h>
#include"fopen.cpp"
using namespace std;
#define int long long
#define itn long long
constexpr int oo = 2503;
//========================================================================
int n;
//========================================================================
int d[oo],low[oo];
int dis[oo][oo],das[oo][oo];
bool vis[oo];
//========================================================================
struct nod{int v,head,nxt,w;}st[oo<<1];
int top=0;
void add(int x,int to,int w){st[++top].v=to;st[top].w=w;st[top].nxt=st[x].head;st[x].head=top;}
//========================================================================
void init(int n){
    top=0;
    memset(das,0,sizeof(das));
    memset(d,0x7f7f,sizeof(d));
    memset(vis,0,sizeof(vis));
    memset(low,0,sizeof(low));
    memset(st,0,sizeof(st));
    for (int i=1;i<=n;i++)
        st[i].head = 0;
}
//========================================================================
void dfs(int x,int fa,int now){
    for(int i=st[x].head;i;i=st[i].nxt){
        int fom=st[i].v;
        if(fa==fom)
            continue;
        das[now][fom]=das[now][x]+st[i].w;
        dfs(fom,x,now);
    }
}
//========================================================================
signed main(){
    fre();
    //========================================================================
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    //========================================================================
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        bool flag = 1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int x;
                cin >> x;
                dis[i][j]=x;
                if(i==j&&x!=0)
                    flag=0;
            }
        }
    //========================================================================
        for(int i=1; i<=n; i++){
            for(int j=1; j<=i; j++){
                if(dis[i][j]!=dis[j][i]){
                    flag=false;
                    break;
                }
            }
        }
    //========================================================================
        if(flag){
            init(n);
    //========================================================================
            d[1]=0;
            for(int i=1;i<=n;i++){
                int x=0;
                for(int j=1;j<=n;j++){
                    if(!vis[j]&&(x==0||d[j]<d[x]))
                        x=j;
                }
                vis[x]=1;
                for(int y=1;y<=n;y++){
                    if(!vis[y]&&dis[x][y]<d[y]){
                        low[y]=x;
                        d[y]=dis[x][y];
                    }
                }
            }
    //========================================================================
            for(int i=2;i<=n;i++){
                add(i,low[i],d[i]);
                add(low[i],i,d[i]);
            }
    //========================================================================
            for(int i=1;i<=n;i++)
                dfs(i,-1,i);
    //========================================================================
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(dis[i][j]!=das[i][j]){
                        flag=false;
                    }
                }
            }
        }
    //========================================================================
        if (!flag) cout << "No" << endl;
        else{
            double maxx=-1;
            int num;
            double tot=0;
            for(int i=1;i<=n;i++){
                double sum=0;
                tot=0;
                for(int j=st[i].head;j;j=st[j].nxt){
                    sum+=st[j].w;
                    tot++;
                }
                if(tot)
                    sum/=(tot*1.0);
                
                if(sum>maxx){
                    maxx=sum;
                    num=i;
                }
            }
            cout << "Yes"<< '\n' << num << '\n';
        }   
    }
    //========================================================================
    return 0;
}

原题codeforces472D,题目强化版。给一个图中的点两两之间的距离,求是不是一棵树。如果是树求相连的边权平均值最大的那个点。

先不管它是不是树,跑最小生成树,算出在MST条件下的dist2数组。如果它是树,显然dist和dist2完全一样。如果不一样,这个图一定不是树。另外Kruskal会被卡。

第二问在第一问的条件下怎么搞都行了

Prim写了半天写的想si


D. 天神下凡

题目背景
Czy找到宝藏获得屠龙宝刀和神秘秘籍!现在他要去找经常ntr他的Jmars报仇……

题目描述
Czy学会了一招“堕天一击”,他对一个地点发动堕天一击,地面上就会留下一个很大的圆坑。圆坑的周围一圈能量太过庞大,因此无法通过。所以每次czy发动技能都会把地面分割。Jmars拥有好大好大的土地,几十眼都望不到头,所以可以假设土地的大小是无限大。现在czy对他发动了猛烈的攻击,他想知道在泽宇攻击之后他的土地被切成几份了?

Czy毕竟很虚,因此圆心都在x坐标轴上。另外,保证所有圆两两之间不会相交。

输入输出格式
输入第一行为整数n,表示czy放了n次堕天一击。

接下来n行,每行两个整数x[i],r[i]。表示在坐标(x[i] , 0)放了一次堕天一击,半径为r[i]。

输出一行,表示地面被分割成几块。

样例输入

4
7 5
-9 11
11 9
0 20

样例输出

6

数据范围
对于30%数据,n<=5000

对于100%数据,1<=n<=300000,-109<=x[i]<=109,1<=r[i]<=10^9.

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int _ =320031;
struct sta{
    LL ld,rd;
}stk[_];
int n,top;
struct cir{
    LL o,r;
}c[_];
bool operator == (cir a,cir b){
    return (a.o==b.o)&(a.r==b.r);
}
bool cmp(cir a,cir b){
    if(a.o-a.r!=b.o-b.r){
        return a.o-a.r<b.o-b.r;
    }
    return a.o+a.r>b.o+b.r;
}
int main(){
    freopen("god.in","r",stdin);
    freopen("god.out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n;
    for(register int i=1;i<=n;++i){
        cin>>c[i].o>>c[i].r;
    }
    sort(c+1,c+n+1,cmp);
    register int ans=1;

    for(register int i=1;i<=n;++i){
        if(c[i]==c[i-1])continue;
        ++ans;
        register LL ld=c[i].o-c[i].r,rd=c[i].o+c[i].r;
        while(top){
            if(stk[top].ld==ld&&stk[top].rd==rd){
                top--;
                ++ans;
                break;
            }
            if(stk[top].ld==ld){
                stk[top].ld=rd;
                break;
            }
            if(ld>=stk[top].rd||(ld>stk[top].ld&&rd<stk[top].rd)){--top;}
            else break;
        }
        stk[++top].ld=ld,stk[top].rd=rd;
    }
    cout<<ans;
}
//代码转自https://blog.csdn.net/JH_2002/article/details/80636247

解释一下题意,

其实就是一条线上,给定n个x,r

求这些个⚪,

将平面分割成了多少块。

一般来说一个圆就是一个贡献
如果一个圆被几个圆内切了,也就是说,从一个范围[l,r]的圆说,如果有若干个[l,p1],[p1,p2],....,[pn,r]的圆,那么会产生额外的贡献。

我们的目标是找到额外的贡献与不重叠的圆的数量

之后用栈做维护就可以了。

标签:oo,czy,2024.6,int,ll,样例,long
From: https://www.cnblogs.com/white-ice/p/18239795

相关文章

  • [考试记录] 2024.6.9
    T3WRONG-Wrongdirections题面翻译FarmerJohn刚刚购买了一台新型可编程拖拉机。为了使拖拉机移动,他输入一串长度为N的绳子(1<=N<=100,000)仅由字符F,L和R组成。每个'F'指示拖拉机向前移动一个单元,并且字符'L'和'R'分别导致左右转90度。拖拉机从原点开始(0,0)朝北。通过输......
  • 2024.6.7
    18万条数据publicclassHotCategoryTop10_3{publicstaticvoidmain(String[]args){//TODO搭建Spark的运行环境SparkConfconf=newSparkConf();conf.setAppName("HotCategoryTop10");conf.setMaster("local[*]&quo......
  • 2024.6.7.exercise
    //#define_CRT_SECURE_NO_WARNINGS//#include<stdio.h>//#include<stdlib.h>//#include<stdbool.h>////typedefintdatatype;//typedefstructtree//{// datatypedata;// structtree*left;// structtree*right;//}tree;////datatype*......
  • 2024.6.7 日记
    今天心情不好,晚上效率很低。先总结一下模拟赛。今天确实打的不好,首先T1这个构造没啥说的,没发现就是没发现,但是freoepn是真逆天,交题前切记,编译一遍先。T2的问题在于维护方式想假导致被耗了好多好多时间,过程中还出现了倍增LCA写错,真的不牛,不过似乎这些时间省下来也没用。......
  • 2024.6.7
    2024.6.7【高考咯!!!学长们加油啊!!!】Friday五月初二A.双色球【题目描述】机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233“来来来,学弟,我考你道水题检验一下你的水平……”一个栈内初始有n个红色和蓝色的小球,请你按照以下规则进......
  • 2024.6.6
    更换了hadoop中的jdk的版本从1.8->17rdd行动算子和转换算子序列化//TODO//Spark在编写代码时,调用转换算子,并不会真正执行,因为只是在Driver端组合功能//所以当前的代码其实就是在Driver端执行//所以当前main方法也称之为driver方法......
  • 2024.6.6 日记
    晚上写不动题,所以打算每天睡前写点神秘文字。明天还有模拟赛,相似。周二T1挂了,凭借神秘的狗运打表瞪出了T2的结论,明天,或者以后,还会有这样的好运吗。呃我要干啥,要不然写点总结。这两天讲了dp,于是我补了一点题,找了一点题。感觉dp的方法其实大概就是,对着一个已知的过程dp,......
  • 2024.6 做题记录
    2024.6做题记录[JSOI2009]球队收益/球队预算考虑到要求最小总支出,想到最小费用流。首先容易发现,每场比赛都只有两种可能,即甲输乙赢或甲赢乙输。但是这样我们在跑费用流的时候显然需要考虑对于两个因素同时的影响,显然这样不好做。我们不妨假设剩下的比赛所有人都输,那么我们......
  • 2024.6.6
    2024.6.6【一天高考!!!“夏天周而复始、该相逢的人会再相逢”】Thursday五月初一<theme=oi-"DP">来学习一下DP的优化其实考试时我应该很难用到优化的P2569[SCOI2010]股票交易DP柿子比较好推,T,Maxp都比较小,作为f数组的两维还是挺合理的。那么设f[i][j]为第i天,有j张......
  • 2024.6.3 时光机会是最没用的发明
    正如标题,时光机会是最无用的发明。如果问昨天的我,时光机有用吗,我会毫不犹豫地回答有用。我希望回到5月,乞求自己好好改初赛;我希望回到1月,乞求自己不要虚度光阴;我希望回到去年9月,乞求自己不要头铁T2,乞求自己检查T1;我希望回到去年6月,乞求自己不要玩florr,这个万恶之源;我希望回到......