#include
#include
#include
using namespace std;
const int maxn=2e4+5;
char str[maxn];
stack<int>stc1;
stack<char>stc2;
int num[maxn];
int tot;
int ans[185];
int b[185];
int a[65];
void toString(int x)
{
for(int i=0;i<181;++i)
b[i]=0;
b[0]=1;
for(int i=0;i<x;++i)
{
for(int j=0;j<181;++j)
{
b[j]*=2;
}
for(int j=0;j<181;++j)
{
if(b[j]>9)
{
b[j+1]++;
b[j]=b[j]%10;
}
}
}
}
void add()
{
for(int i=0;i<181;++i)
{
ans[i]+=b[i];
if(ans[i]>9)
{
ans[i+1]++;
ans[i]=ans[i]%10;
}
}
}
int main()
{
a[0]=1;
for(int i=1;i<=30;++i)
{
a[i]=a[i-1]*2;
//cout<
}
scanf("%s",str);
for(int i=0;str[i];++i)
{
if(str[i]=='2')
{
if(!stc2.empty())
stc1.push(str[i]-'0');
if(stc2.empty()&&str[i+1]!='(')
{
num[++tot]=1;
toString(1);
add();
}
else
if(stc2.empty())
stc1.push(str[i]-'0');
}
if(str[i]=='0')
stc1.push(str[i]-'0');
if(str[i]=='(')
stc2.push(str[i]);
if(str[i]==')')
{
int s=0;
while(stc2.top()!='(')
{
stc2.pop();
s+=stc1.top();
stc1.pop();
// cout<
}
stc2.pop();
s+=stc1.top();
stc1.pop();
stc1.pop();
//cout<
//cout<
if(stc2.empty())
{
//cout<
toString(s);
add();
continue;
}
//cout<
//cout<
stc1.push(a[s]);
}
if(str[i]=='+')
{
if(!stc2.empty())
stc2.push(str[i]);
}
}
int len;
for(int i=180;i>=0;i--)
{
if(ans[i]!=0)
{
len=i;
break;
}
}
for(int i=len;i>=0;i--)
{
printf("%d",ans[i]);
}
printf("\n");
return 0;
}
进而可以推出下式。
我们知道,gcd(xi,yj),就是 xi 与 yj 的公共质因子最小数量幂次的乘积,如下。
根据这个式子,可以将原式变为如下表示。
我们将最里面的连乘提到最外面,就可以将连乘转化为幂次求和。
然后,我们枚举 i ,因为此时 i,cntx[k],cnty[k]都是固定的,所以我们可以算出在哪个范围取 i·cntx[k],在哪个范围取 j·cnty[k] 。
因此求和可以直接算出来。
其中,edge=i·cntx[k]/cnty[k]向下取整。
这样,我们就可以在时间复杂度内算出答案。这里还可以改一下边界,min(d,max(c-1,edge)),这样就可以只用中间的式子去计算了。
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll a,b,c,d,x,y;
map<ll,pair<ll,ll > >fac;
ll quickpow(ll p,__int128 q)
{
ll res=1;
while(q)
{
if(q&1)
res=res*p%mod;
q>>=1;
p=p*p%mod;
}
return res;
}
void getfac(ll p,bool tag)
{
for(int i=2;i*i<=p;++i)
{
while(p%i==0)
{
tag?fac[i].second++:fac[i].first++;
p/=i;
}
}
if(p!=1)
tag?fac[p].second++:fac[p].first++;
}
int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&x,&y);
getfac(x,0);
getfac(y,1);
ll ans=1;
for(auto k:fac)
{
if(!k.second.second)
continue;
__int128 res=0;
for(ll i=a;i<=b;++i)
{
ll edge=k.second.first*i/k.second.second;
edge=min(d,max(c-1,edge));
res+=(d-edge)*k.second.first*i;
res+=k.second.second*(edge+c)*(edge-c+1)/2;
}
ans=ans*quickpow(k.first,res)%mod;
}
printf("%lld\n",ans);
return 0;
}
#include
#include
#include
using namespace std;
const int maxn=2e6+5;
const int inf=0x3f3f3f3f;
struct node
{
int id,val;
}a[maxn];
int n,m,k,x,cnt;
bool cmp(node p,node q)
{
return p.val<q.val;
}
int vis[maxn];
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%d",&k);
for(int j=1;j<=k;++j)
{
scanf("%d",&x);
a[++cnt]={i,x};
}
}
sort(a+1,a+1+cnt,cmp);
int l=1,r=0;
int res=0;
int ans=inf;
bool flag=0;
while(r<cnt)
{
while(res<m)
{
r++;
if(r>cnt)
{
flag=1;
break;
}
if(!vis[a[r].id])
res++;
vis[a[r].id]++;
}
if(flag)
break;
ans=min(ans,a[r].val-a[l].val);
while(res>=m)
{
vis[a[l].id]--;
if(!vis[a[l++].id])
res--;
else
ans=min(ans,a[r].val-a[l].val);
}
}
printf("%d\n",ans);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];
int T,n;
void multiply(int x)
{
for(int i=n-1;i>=1;i--)
{
b[i]*=x;
}
for(int i=n-1;i>=1;i--)
{
if(b[i]>9)
{
b[i-1]+=b[i]/10;
b[i]=b[i]%10;
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
b[0]=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
int l=1;
while(!a[l])
l++;
int tmp=a[l];
b[1]=a[l+1];
for(int i=1;i<l;++i)
b[i+1]=0;
for(int i=l+2;i<=n;++i)
b[i-1]=a[i];
multiply(tmp);
int st;
if(b[0])
st=0;
else
st=1;
for(int i=st;i<n;++i)
printf("%d",b[i]);
puts("");
}
return 0;
}
#include
#include
#include
#include
using namespace std;
const int maxn=25e4+2;
const int maxm=505;
int n,m;
int a[maxm][maxm];
int dp[maxn<<1],pky[maxm],sum[maxm][maxm];
int ans;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
int x;
scanf("%d",&x);
if(x)
a[i][j]++;
else
a[i][j]--;
sum[i][j]=sum[i-1][j]+a[i][j];
}
pky[0]=maxn;//初始为maxn相当于0
for(int i=1;i<n;++i)//枚举行
for(int j=i+1;j<=n;++j)//枚举下一行
{
int pre=1;
for(int k=1;k<=m;++k)//枚举列
{
if(a[i][k]^1||a[j][k]^1)//成立说明该行没有连续的1不能作为边界
{
for(int l=pre;l<=k;++l)
if(sum[j][l]-sum[i-1][l]==j-i+1)
{
dp[pky[l]]--;//减去其贡献
}
pre=k+1;
pky[k]=maxn;
continue;
}
if(sum[j][k]-sum[i-1][k]==j-i+1)
ans+=dp[pky[k-1]]+dp[pky[k-1]-1]+dp[pky[k-1]+1];
pky[k]=pky[k-1]+sum[j-1][k]-sum[i][k];
if(sum[j][k]-sum[i-1][k]==j-i+1)
dp[pky[k]]++;
}
for(int l=pre;l<=m;++l)
if(sum[j][l]-sum[i-1][l]==j-i+1)
dp[pky[l]]--;
}
printf("%d\n",ans);
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+5;
int n,t,cnt,tot,wh;
bool vis[maxn];
int ma;
int a[maxn];
int d[maxn];
int q[maxn];
struct node
{
int to,next;
}edge[maxn<<1];
int head[maxn],pre[maxn];
void add(int x,int y)
{
edge[++cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt;
}
void bfs()
{
int hh=0,tt=0;
q[0]=1;
vis[1]=1;
pre[1]=-1;
while(hh<=tt)
{
int t=q[hh++];
for(int i=head[t];i;i=edge[i].next)
{
int ver=edge[i].to;
if(!vis[ver])
{
vis[ver]=1;
pre[ver]=t;
if(ver==n)
return;
q[++tt]=ver;
}
}
}
}
void dfs1(int u,int fa)
{
for(int i=head[u];i;i=edge[i].next)
{
int ver=edge[i].to;
if(ver==fa)
continue;
d[ver]=d[u]+1;
dfs1(ver,u);
}
}
void dfs2(int u,int fa,int cost)
{
bool flag=0;
for(int i=head[u];i;i=edge[i].next)
{
int ver=edge[i].to;
if(ver==fa)
continue;
flag=1;
//cout<
if(cost+1>=((d[ver]/2)+(d[ver]%2)))
ma=max(ma,cost+1);
else
dfs2(ver,u,cost+1);
}
if(!flag)
ma=max(ma,d[u]/2+d[u]%2);
}
int main()
{
ma=0;
scanf("%d%d",&n,&t);
for(int i=1;i<n;++i)
{
int x,y;
scanf("%d %d",&x,&y);
add(x,y);
add(y,x);
}
bfs();
for(int i=n;i!=-1;i=pre[i])
{
a[++tot]=i;
}
if(tot<=t+1)
{
puts("0");
return 0;
}
int root=a[tot-t];
//cout<
dfs1(n,-1);
//for(int i=1;i<=n;++i)
//cout<
dfs2(root,-1,0);
printf("%d\n",ma);
return 0;
}