Gym102040 .Asia Dhaka Regional Contest(寒假自训第9场)

Stella981
• 阅读 636

B .Counting Inversion

题意:给定L,R,求这个区间的逆序对数之和。(L,R<1e15)

思路:一看这个范围就知道是数位DP。 只是维护的东西稍微多一点,需要记录后面的各种数字的个数cnt,以及逆序对和sum,以及出现了多少种后缀num。

那么枚举到当前位时,假设为i ,那么sum+=cnt[i+1]+cnt[i+2]+....cnt[9];  cnt[i]+=num; 可以参考CF1073E

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
struct in{
    ll num,cnt[10],sum;
    in(){num=sum=0; memset(cnt,0,sizeof(cnt)); }
}dp[16];
int q[20],tot,vis[16];
in dfs(int pos,int st,int lim)
{
    if(!lim&&vis[pos]) return dp[pos];
    if(pos==1) {
        in res;  res.num=1;
        return res;
    }
    int up=9; in res,tmp; if(lim) up=q[pos-1];
    rep(i,0,up){
        tmp=dfs(pos-1,i,lim&&i==up);
        res.sum+=tmp.sum;
        rep(j,i+1,9) res.sum+=tmp.cnt[j];
        rep(j,0,9) res.cnt[j]+=tmp.cnt[j];
        res.cnt[i]+=tmp.num;
        res.num+=tmp.num;
    }
    vis[pos]=1;
    return dp[pos]=res;
}
ll cal(ll x)
{
    if(x<10) return 0;
    tot=0; ll ans=0;
    while(x) q[++tot]=x%10,x/=10;
    memset(dp,0,sizeof(dp));
    memset(vis,0,sizeof(vis));
    rep(i,1,tot){
        ll up=9; if(i==tot) up=q[tot];
        rep(j,1,up){
             in tmp=dfs(i,j,(i==tot)&&(j==q[tot]));
             ans+=tmp.sum;
             rep(k,j+1,9) ans+=1LL*tmp.cnt[k];
        }
    }
    return ans;
}
int main()
{
    ll L,R;  int T,Ca=0; scanf("%d",&T);
    while(T--){
       scanf("%lld%lld",&L,&R);
       printf("Case %d: %lld\n",++Ca,cal(R)-cal(L-1));
    }
    return 0;
}

C .Divisors of the Divisors of An Integer

题意:给出N,问N!的因子的因子个数和。

思路:唯一分解,对于一个素数p,假设它的幂次是x,那么因子的幂次有0,1,2,...x;那么因子的因子幂次就是(0); (0,1); ( 0,1,2);   ... ; (0,1,2,...x)

所以就是一个累乘,对于每个素数p,ans*=(x+1)*(x+2)/2;    而阶乘的唯一分解只需要一直除即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
const int Mod=1e7+7;
int a[maxn],N,p[maxn],vis[maxn],cnt;ll ans=1;
int solve(int p)
{
    int tN=N,res=0;
    while(tN) {
        res+=tN/p;
        if(res>Mod) res-=Mod;
        tN/=p;
    } return res;
}
int get(int p)
{
    if(p&1) return 1LL*(p+1)/2*p%Mod;
    return 1LL*p/2*(p+1)%Mod;
}
int main()
{
    rep(i,2,1000000){
        if(!vis[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<=1000000;j++){
            vis[p[j]*i]=1;
            if(i%p[j]==0) break;
        }
    }
    while(~scanf("%d",&N)&N){
       ans=1;
       rep(i,2,N) {
          if(!vis[i]) a[i]=solve(i);
       }
       rep(i,2,N){
         if(a[i])
           ans=(ll)ans*get(a[i]+1)%Mod;
       }
       printf("%lld\n",ans);
    }
    return 0;
}

E.Helping the HR

题意:给定每个人的签到和离开时间,问每个人的..情况

思路:模拟; by许。

#include<bits/stdc++.h>
using namespace std;
char str[30];
int main()
{
    int n,s=17*1800,D=19*1800,E=25*1800;
    while(~scanf("%d",&n)&&n)
    {
        int cnt=0;
        for(int cas=0;cas<n;cas++)
        {
            int S=0,T=0,tot=0,pre=0,p=3600;
            scanf("%s",str);
            int len=strlen(str);
            for(int i=2;i<len;i++)
            {
                if(str[i]!=':'&&i!=len-1)pre=pre*10+str[i]-'0';
                else
                {
                    if(i==len-1)pre=pre*10+str[i]-'0';
                    tot++;
                    if(tot<=3)
                    {
                        S+=pre*p;
                        if(tot==3)p=3600;
                        else p/=60;
                    }
                    else T+=pre*p,p/=60;
                    pre=0;
                }
            }
            int flag=0;
            if(str[0]=='D'&&S>D)flag=1;
            if(str[0]=='E'&&S>E)flag=1;
            int res=T-max(s,S);
            if(str[0]=='D'&&res<8*3600)flag=1;
            if(str[0]=='E'&&res<9*3600)flag=1;
            cnt+=flag;            
        }
        if(!cnt)puts("All OK");
        else if(cnt<=3)printf("%d Point(s) Deducted\n",cnt);
        else puts("Issue Show Cause Letter");
    }        
}

F .Path Intersection

题意:给定一棵树, Q次询问,每次给定K条路经,求这K条路有多少个公共点.

思路:路剖,  即每条路经+1, 然后可以选一条路径看有多少个点被覆盖K次。

好久没写树剖了,开始写错的地方提醒下自己:  当top不同的时候,我们先操作dep[top[]]大的,然后把它变为fa[top[]];

而top相同的,正常的从小到大即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
int Laxt[maxn],Next[maxn],To[maxn],cnt,dep[maxn];
int sz[maxn],son[maxn],top[maxn],pos[maxn],N;
int Mx[maxn],num[maxn],Lazy[maxn],fa[maxn],tot;
void add(int u,int v){
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs1(int u,int f)
{
    sz[u]=1;  fa[u]=f;
    dep[u]=dep[f]+1; son[u]=0;
    for(int i=Laxt[u];i;i=Next[i]){
        if(To[i]!=f){
            dfs1(To[i],u);
            if(sz[To[i]]>sz[son[u]]) son[u]=To[i];
        }
    }
}
void dfs2(int u,int Top)
{
    pos[u]=++tot; top[u]=Top;
    if(son[u]) dfs2(son[u],Top);
    for(int i=Laxt[u];i;i=Next[i]){
      if(To[i]!=fa[u]&&To[i]!=son[u])
         dfs2(To[i],To[i]);
    }
}
void build(int Now,int L,int R)
{
    Mx[Now]=Lazy[Now]=0; num[Now]=R-L+1;
    if(L==R) return; int Mid=(L+R)>>1;
    build(Now<<1,L,Mid); build(Now<<1|1,Mid+1,R);
}
void pushdown(int Now)
{
    if(Lazy[Now]) {
        Mx[Now<<1]+=Lazy[Now];Lazy[Now<<1]+=Lazy[Now];
        Mx[Now<<1|1]+=Lazy[Now];Lazy[Now<<1|1]+=Lazy[Now];
        Lazy[Now]=0;
    }
}
void pushup(int Now)
{
    Mx[Now]=Mx[Now<<1]; num[Now]=num[Now<<1];
    if(Mx[Now<<1|1]>Mx[Now])
      Mx[Now]=Mx[Now<<1|1],num[Now]=num[Now<<1|1];
    else if(Mx[Now<<1|1]==Mx[Now])
      num[Now]+=num[Now<<1|1];
}
void update(int Now,int L,int R,int l,int r,int val)
{
    if(l<=L&&r>=R){
        Mx[Now]+=val; Lazy[Now]+=val; return ;
    }
    pushdown(Now); int Mid=(L+R)>>1;
    if(l<=Mid) update(Now<<1,L,Mid,l,r,val);
    if(r>Mid) update(Now<<1|1,Mid+1,R,l,r,val);
    pushup(Now);
}
int query(int Now,int L,int R,int l,int r,int K)
{
    if(Mx[Now]<K) return 0;
    if(l<=L&&r>=R) return Mx[Now]==K?num[Now]:0;
    pushdown(Now); int Mid=(L+R)>>1,res=0;
    if(l<=Mid) res+=query(Now<<1,L,Mid,l,r,K);
    if(r>Mid) res+=query(Now<<1|1,Mid+1,R,l,r,K);
    pushup(Now); return res;
}
void pathup(int u,int v,int val)
{
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        update(1,1,N,pos[top[u]],pos[u],val);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    update(1,1,N,pos[u],pos[v],val);
}
int pathquery(int u,int v,int K)
{
    int res=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        res+=query(1,1,N,pos[top[u]],pos[u],K);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    res+=query(1,1,N,pos[u],pos[v],K);
    return res;
}
int a[maxn],b[maxn];
int main()
{
    int T,Q,K,C=0,u,v;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        rep(i,1,N) Laxt[i]=0; cnt=0; tot=0;
        rep(i,1,N-1){
            scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        dfs1(1,0); dfs2(1,1);
        build(1,1,N);
        scanf("%d",&Q);
        printf("Case %d:\n",++C);
        while(Q--){
            scanf("%d",&K);
            rep(i,1,K) scanf("%d%d",&a[i],&b[i]);
            rep(i,1,K) pathup(a[i],b[i],1);
            printf("%d\n",pathquery(a[1],b[1],K));
            rep(i,1,K) pathup(a[i],b[i],-1);
        }
    }
    return 0;
}

I .Triangles

题意:给定两个三维空间里的三角形,求最近距离。

思路:好像是不错的题,想补。

J. VAT Man

签到。 by许。

#include<bits/stdc++.h>
#define db double
using namespace std;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        db x;
        cin>>x;
        printf("%.2lf\n",x*1.15);
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这