前些天拜年咕了,今天成功被fcy带飞了
fcy代码:
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int Mod=998244353;
struct in{
ll num,sum,cnt[10];
in(){num=sum=0; memset(cnt,0,sizeof(cnt)); }
}dp[16][10];
int v[20],q[20],tot,vis[16][10];
in dfs(int pos,int st,int lim)
{
if(!lim&&vis[pos][st]) return dp[pos][st];
if(pos==1) {
in res; res.num=1;//res.cnt[st]=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][st]=1;
return dp[pos][st]=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()
{
v[1]=1; rep(i,2,18) v[i]=(ll)v[i-1]*10%Mod;
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;
}
/*
5
1 9
1 100
50 60
23 2343
345 99373
*/
C.Divisors of the Divisors of An Integer
fcy代码:
#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;
}
题意:规定白班必须要9.30之前到公司,上班时间最少8小时,晚班必须12.30之前到公司,上班时间最少9小时,且计算上班时间最早从8.30开始,如果一个人上班迟到或者早退,会被扣分,一个月扣3分以上会被发邮件,给出n天上班时间,判断最后的状态。
水题。
#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");
}
}
/*
3
D:8:30:00:17:30:20
D:9:30:01:17:30:20
E:11:30:01:20:31:00
3
D:8:30:00:16:30:00
D:9:30:00:17:30:20
E:11:30:01:20:31:00
3
D:8:30:00:17:30:20
D:9:30:01:17:30:20
E:11:30:01:20:00:00
4
D:8:00:00:16:15:20
D:9:30:01:17:30:00
E:11:30:01:20:00:00
E:11:30:01:20:00:00
*/
题意:给出k条a到b的路径,求k条路径的公共点。
思路:先树剖,然后k次区间+1,最后查询区间内最小值=k的点的个数即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int id[maxn],dep[maxn],cnt;
int top[maxn],size[maxn],f[maxn],son[maxn];
vector<int>G[maxn];
int tag[maxn*4],mx[maxn*4],mn[maxn*4];
void dfs1(int u,int fa,int deep)
{
f[u]=fa;
size[u]=1;
dep[u]=deep;
son[u]=0;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa)continue;
dfs1(v,u,deep+1);
size[u]+=size[v];
if(size[v]>size[son[u]])son[u]=v;
}
}
void dfs2(int u,int root)
{
top[u]=root;
id[u]=++cnt;
if(son[u])dfs2(son[u],root);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==f[u]||v==son[u])continue;
dfs2(v,v);
}
}
void pushdown(int o,int ls,int rs,int l,int m,int r)
{
if(tag[o]!=0&&l!=r)
{
mx[ls]+=tag[o],mx[rs]+=tag[o];
mn[ls]+=tag[o],mn[rs]+=tag[o];
tag[ls]+=tag[o],tag[rs]+=tag[o];
tag[o]=0;
}
}
void update(int o,int l,int r,int ql,int qr,int v)
{
int m=(l+r)/2,ls=o*2,rs=o*2+1;
pushdown(o,ls,rs,l,m,r);
if(l>=ql&&r<=qr)
{
mx[o]+=v,mn[o]+=v,tag[o]+=v;
return;
}
if(ql<=m)update(ls,l,m,ql,qr,v);
if(qr>m)update(rs,m+1,r,ql,qr,v);
mx[o]=max(mx[ls],mx[rs]);
mn[o]=min(mn[ls],mn[rs]);
}
int query(int o,int l,int r,int ql,int qr,int k)
{
int m=(l+r)/2,ls=o*2,rs=o*2+1,res=0;
pushdown(o,ls,rs,l,m,r);
if(mx[o]<k)return 0;
if(mn[o]==k)return min(r,qr)-max(l,ql)+1;
if(ql<=m)res+=query(ls,l,m,ql,qr,k);
if(qr>m)res+=query(rs,m+1,r,ql,qr,k);
return res;
}
void up_path(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,cnt,id[top[x]],id[x],z);
x=f[top[x]];
}
if(id[x]>id[y])swap(x,y);
update(1,1,cnt,id[x],id[y],z);
}
int qu_path(int x,int y,int z)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(1,1,cnt,id[top[x]],id[x],z);
x=f[top[x]];
}
if(id[x]>id[y])swap(x,y);
ans+=query(1,1,cnt,id[x],id[y],z);
return ans;
}
int a[55],b[55];
int main()
{
int T,n,k,u,v,q,Case=0;
scanf("%d",&T);
while(T--)
{
printf("Case %d:\n",++Case);
scanf("%d",&n);
for(int i=1;i<=n;i++)G[i].clear();
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
cnt=0;
dfs1(1,0,1);
dfs2(1,1);
scanf("%d",&q);
while(q--)
{
scanf("%d",&k);
for(int i=1;i<=k;i++)
scanf("%d%d",&a[i],&b[i]),up_path(a[i],b[i],1);
printf("%d\n",qu_path(a[1],b[1],k));
for(int i=1;i<=k;i++)up_path(a[i],b[i],-1);
}
}
}
/*
2
6
1 2
2 3
3 4
2 5
2 6
2
2
4 5
3 6
3
4 5
3 1
2 6
2
1 2
1
2
1 1
2 2
*/