IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> CodeForces616:Educational Round 5 -> 正文阅读

[网络协议]CodeForces616:Educational Round 5

前言

比较简单的一场比赛。
ABC是水题。
D简单双指针。
E整除分块板子题。
F广义SAM板子,但是由于我太蒻不会,所以只能拿SA硬做qwq

A?Comparing?Two?Long?Integers \text{A Comparing Two Long Integers} A?Comparing?Two?Long?Integers

Description \text{Description} Description

比较两个不超过 1000000 1000000 1000000 位的正整数的大小。正整数可能有前导零。前面那个比后面那个大输出 >,比后面那个小输出 <,两个一样大输出 =

Solution \text{Solution} Solution

python爪把
读进来后去掉前导零再判断即可。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1e6+100;
const int M=505;

char a[N],b[N];
int n,m,q,tim;


signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  scanf(" %s %s",a+1,b+1);
  n=strlen(a+1);m=strlen(b+1);
  int pa=1,pb=1;
  while(pa<=n&&a[pa]=='0') pa++;
  while(pb<=m&&b[pb]=='0') pb++;
  if(n-pa+1!=m-pb+1){
    if(n-pa+1<m-pb+1) putchar('<');
    else putchar('>');
    return 0;
  }
  while(pa<=n){
    if(a[pa]!=b[pb]){
      if(a[pa]<b[pb]) putchar('<');
      else putchar('>');
      return 0;
    }
    ++pa;++pb;
  }
  putchar('=');
  return 0;
}
/*
 */

B?Dinner?with?Emma \text{B Dinner with Emma} B?Dinner?with?Emma

Descripion \text{Descripion} Descripion

杰克决定邀请艾玛出去吃饭。杰克是个谦虚的学生,他不想去昂贵的餐馆。可艾玛是个品味很高的女孩,她更喜欢高端的餐馆。

Munhatan由 n n n 条街道和 m m m 条巷子组成。在每一条街道和小巷的交叉口都有一家餐馆。街道用 1 1 1 n n n 的整数来编号,巷子用从 1 1 1 m m m 的整数来编号。在第 i i i 街和第 j j j 巷交叉口的餐馆里吃饭的费用是 C i , j C_{i,j} Ci,j?

杰克和艾玛决定按以下方式选择餐馆。先是艾玛选了在哪条街上吃饭,然后杰克选了巷子。艾玛和杰克做出了最佳的选择:艾玛想最大限度地提高晚餐的成本,杰克想把它降到最低。而艾玛知道杰克的想法。告诉这对恋人晚餐最终的费用。
n , m ≤ 100 n,m\le 100 n,m100

Solution \text{Solution} Solution

tag:min-max 容斥。
找到每一行最小值的最大值即可。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1e6+100;
const int M=505;

int n,m;
int a[105][105];

signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();m=read();
  int ans=0;
  for(int i=1;i<=n;i++){
    int mn(2e9);
    for(int j=1;j<=m;j++) a[i][j]=read(),mn=min(mn,a[i][j]);
    ans=max(ans,mn);
  }
  printf("%d\n",ans);
  return 0;
}
/*
 */

C?The?Labyrinth \text{C The Labyrinth} C?The?Labyrinth

Descripion \text{Descripion} Descripion

给你一张图,* 表示墙,.表示空地,问每个 * 周围的联通快中 . 的数量和模 10 10 10 的结果,属于同一个联通快的只计算一次。
n , m ≤ 1000 n,m\le 1000 n,m1000

Solution \text{Solution} Solution

bfs 一遍求出每个连通块的大小,求出每个点四周的大小之和即可。
可以利用 set 方便去重。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1050;

int n,m;
int a[N][N],bel[N][N],siz[N*N],tot,vis[N][N];
int dx[5]={0,0,-1,0,1},dy[5]={0,-1,0,1,0};
inline bool exi(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;}
void bfs(int x,int y,int f){
  vis[x][y]=1;bel[x][y]=f;siz[f]++;
  for(int i=1;i<=4;i++){
    int xx=x+dx[i],yy=y+dy[i];
    if(vis[xx][yy]||a[xx][yy]||!exi(xx,yy)) continue;
    bfs(xx,yy,f);
  }
  return;
}
set<int>s;

signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();m=read();
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      char c;scanf(" %c",&c);
      a[i][j]=(c=='*');
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      if(a[i][j]||vis[i][j]) continue;
      ++tot;bfs(i,j,tot);
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
      if(!a[i][j]){
	putchar('.');continue;
      }
      for(int k=1;k<=4;k++){
	int x=i+dx[k],y=j+dy[k];
	if(a[x][y]||!exi(x,y)) continue;
	s.insert(bel[x][y]);
      }
      int ans(1);
      for(int x:s) ans+=siz[x];
      printf("%d",ans%10);
      s.clear();
    }
    putchar('\n');
  }
  return 0;
}
/*
 */

D?Longest?k-Good?Segment \text{D Longest k-Good Segment} D?Longest?k-Good?Segment

Descripion \text{Descripion} Descripion

给定一个包含 n n n 个整数的序列 a a a 0 ≤ a i ≤ 1 0 6 0\le a_i \le 10^6 0ai?106 ,询问不重复数字个数 ≤ k \le k k 的最长区间的左右端点。如果有多解输出任意一组。
n ≤ 5 × 1 0 5 n\le 5\times10^5 n5×105

Solution \text{Solution} Solution

开一个桶维护各种数字的数量维护当前区间不重复数字个数,双指针取区间最大值即可。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1e6+100;

int n,m;
int a[N],bac[N],now,ans,L,R;

signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();m=read();
  for(int i=1;i<=n;i++) a[i]=read();
  int l=1,r=0;
  while(r<n){
    now+=(++bac[a[++r]]==1);
    while(now>m) now-=(--bac[a[l++]]==0);
    if(r-l+1>ans){
      ans=r-l+1;L=l;R=r;
    }
  }
  printf("%d %d\n",L,R);
  return 0;
}
/*
 */

E?Sum?of?Remainders \text{E Sum of Remainders} E?Sum?of?Remainders

Descripion \text{Descripion} Descripion

计算以下式子的和: n ? m o d ? 1 + n ? m o d ? 2 + n ? m o d ? 3 + ? + n ? m o d ? m n \bmod 1 + n \bmod 2 + n \bmod 3 + \dots + n \bmod m nmod1+nmod2+nmod3+?+nmodm。由于结果可能很大,你需要输出其对 1 0 9 + 7 10^9+7 109+7 取模的结果。
n , m ≤ 1 0 1 3 n,m\le 10^13 n,m1013

Solution \text{Solution} Solution

式子可以写成:
∑ i = 1 m n ? ? n i ? × i \sum_{i=1}^mn-\lfloor\frac{n}{i}\rfloor\times i i=1m?n??in??×i
直接上整除分块即可。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1e6+100;
const int mod=1e9+7;

ll n,m,ans;
ll ksm(ll x,ll k){
  ll res(1);
  while(k){
    if(k&1) res=res*x%mod;
    x=x*x%mod;
    k>>=1;
  }
  return res;
}

inline ll calc(ll l,ll r){return ((l+r)%mod)*((r-l+1)%mod)%mod*500000004%mod;}
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();m=read();
  ans=(m%mod)*(n%mod)%mod;
  for(ll l=1,r;l<=min(n,m);l=r+1){
    r=min(m,n/(n/l));
    ll o=n/l%mod;
    ans=(ans+mod-o*calc(l,r)%mod)%mod;
    //printf("(%lld %lld) o=%lld\n",l,r,o);
  }
  printf("%lld\n",ans);
  return 0;
}
/*
 */

F?Expensive?Strings \text{F Expensive Strings} F?Expensive?Strings

Descripion \text{Descripion} Descripion

给你 n n n个字符串。每个字符串的成本都是 c i c_i ci?
定义字符串的函数,其中 f ( s ) = ∑ i = 1 n c i ? p s , i ? ∣ s ∣ f(s)=\sum_{i=1}^n c_i \cdot p_{s,i} \cdot |s| f(s)=i=1n?ci??ps,i??s p s , i p_{s,i} ps,i? s s s t i t_i ti?中出现的次数, ∣ s ∣ |s| s是字符串 s s s的长度。求所有字符串函数 f ( s ) f(s) f(s)的最大值

注意字符串 s s s不一定 t t t中的某个字符串。

Solution \text{Solution} Solution

据说用广义 SAM 的话就是板子了。
但是我并不会qwq。
考虑使用 SA。

先把所有串连起来,中间夹一些泥巴。
后缀排序后先求出 height ? \operatorname{height} height
每个后缀的价值定义为其所属串的价值,并求出价值的前缀和。
然后如果选择区间 [ l , r ] [l,r] [l,r] 的所有字符串,那么选择的价值就是:
( min ? i = l + 1 r height ? i ) × s u m r ? s u m l ? 1 (\min_{i=l+1}^{r}\operatorname{height}_i )\times sum_r-sum_{l-1} (i=l+1minr?heighti?)×sumr??suml?1?
因为贪心的考虑一定使这个串最长。
那么我们悬线法求出每个 h e i g h t height height 作为最小值的有效区间,扫一遍取最大值即可。
但这样是无法考虑这个串只出现一遍的情况的,这个串一定就是某个串本身,map 暴力判一下即可。

Code \text{Code} Code

# include <bits/stdc++.h>
# include <bits/extc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int N=1e6+100;
const int mod=1e9+7;

int n,m,tot;
int sa[N],rk[N],id[N],oldrk[N],bel[N],len[N],p,cnt[1234567],a[N],l[N],r[N];
ll h[N],c[N];
void calc(){
  for(int k=0,i=1;i<=n;i++){
    if(k) --k;
    while(a[i+k]==a[sa[rk[i]-1]+k]) ++k;
    h[rk[i]]=k;
  }
  return;
}
bool jd[N];
ll ans,sum[N];
string s[N];
map<string,int>mp;

signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  m=read();
  for(int i=1;i<=m;i++){
    cin>>s[i];
    n=s[i].size();
    for(int j=0;j<n;j++) a[++tot]=s[i][j]-'a'+1,bel[tot]=i;
    a[++tot]=i+26;
    bel[tot]=i;jd[tot]=1;
    len[i]=n;
    mp[s[i]]++;
  }
  for(int i=1;i<=m;i++) c[i]=read();//ans=max(ans,c[i]*len[i]);
  for(int i=1;i<=m;i++) if(mp[s[i]]==1) ans=max(ans,c[i]*len[i]);
  n=tot;
  m+=26;
  for(int i=1;i<=n;i++) ++cnt[rk[i]=a[i]];
  for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
  for(int i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;
  for(int w=1;;w<<=1){
    p=0;
    for(int i=n;i>n-w;i--) id[++p]=i;
    for(int i=1;i<=n;i++){
      if(sa[i]>w) id[++p]=sa[i]-w;
    }
    memset(cnt,0,sizeof(cnt));
    memcpy(oldrk,rk,sizeof(rk));
    //for(int i=1;i<=n;i++) printf("%d ",id[i]);
    //putchar('\n');
    for(int i=n;i>=1;i--) ++cnt[rk[id[i]]];
    for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
    for(int i=n;i>=1;i--) sa[cnt[rk[id[i]]]--]=id[i];
    p=0;
    for(int i=1;i<=n;i++){
      if(oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w]) rk[sa[i]]=p;
      else rk[sa[i]]=++p;
    }
    m=p;
    //for(int i=1;i<=n;i++) printf("%d ",sa[i]);
    //putchar('\n');
    if(m==n) break;
  }
  calc();
  for(int i=1;i<=n;i++) sum[i]=sum[i-1]+c[bel[sa[i]]];  
  for(int i=1;i<=n;i++){
    l[i]=i;
    //printf("i=%d\n",i);
    while(l[i]>1&&h[l[i]-1]>=h[i]) l[i]=l[l[i]-1];
  }
  for(int i=n;i>=1;i--){
    r[i]=i;
    while(r[i]<n&&h[r[i]+1]>=h[i]) r[i]=r[r[i]+1];
  }
  //for(int i=1;i<=n;i++){
    //printf("i=%d pl=%d h=%lld l=%d r=%d sum=%lld tmp=%lld\n",
    //	   i,sa[i],h[i],l[i],r[i],sum[i],h[i]*(sum[r[i]]-sum[max(0,l[i]-2)]));
  //}
  for(int i=2;i<=n;i++){   
      ans=max(ans,h[i]*(sum[r[i]]-sum[max(0,l[i]-2)]));
  }
  printf("%lld\n",ans);
  return 0;
}
/*
5
bbbab
bbaab
bbbaa
bbabb
babba
3 -9 8 -3 9 
 */

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:20:18  更:2022-01-01 14:21:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/23 4:48:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码