水题,取下模就可以了。
#include
using namespace std;
typedef long long ll;
const int N=1e6+10;
int a[N],b[N];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
if(a[i]<=0) {
a[i]=a[i]%7+7;
}
else if(a[i]>7){
a[i]=a[i]%7;
if(a[i]==0) a[i]=7;
}
if(a[i]!=4&&a[i]!=7) b[i]=1;
}
int ans=0;
int pre=0;
for(int i=1;i<=n;++i){
if(b[i]) pre++;
else{
ans=max(ans,pre);
pre=0;
}
}
ans=max(ans,pre);
printf("%d\n",ans);
}
水题加一
枚举每条边,那么这条边的花费值就是(左边人数*右边点数+右边点数*左边点数)*这条边权值
#include
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll ans[N];
ll a[N],dp[N],sz[N];
int n,cnt;
int head[N];
ll sum;
struct edge
{
int v,ne,w,id;
}e[N*2];
void dfs(int u,int fa)
{
dp[u]=a[u];
sz[u]++;
for(int i=head[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(v==fa) continue;
dfs(v,u);
dp[u]+=dp[v];
sz[u]+=sz[v];
ans[e[i].id]=2ll*(dp[v]*(n-sz[v])+(sum-dp[v])*sz[v])*w;
//printf("id:%d %lld %lld %lld %lld\n",e[i].id,dp[v],n-sz[v],sum-dp[v],sz[v]);
}
}
void add(int u,int v,int w,int id)
{
e[++cnt]={v,head[u],w,id};
head[u]=cnt;
e[++cnt]={u,head[v],w,id};
head[v]=cnt;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
sum+=a[i];
}
for(int i=1;i
由于k<=10,那么对于k=1,2,。。k每个长度都弄一个权值树状数组维护个数。
每次新增一个值,那么就求k-1的和来更新k这个树状数组里面a[i]所在的权值下标即可。
#include
using namespace std;
typedef long long ll;
const int N=5e5+10;
int tr[15][N];
int a[N],n,k,X[N],len;
const int mod=998244353;
int getid(int x)
{
return lower_bound(X+1,X+1+len,x)-X;
}
int low(int x)
{
return x&(-x);
}
void add(int ty,int x,ll val)
{
for(int i=x;i<=len;i+=low(i)){
tr[ty][i]+=val;
tr[ty][i]%=mod;
}
}
int qu(int ty,int x)
{
ll res=0;
for(int i=x;i;i-=low(i)) {
res=(res+tr[ty][i])%mod;
}
return res;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) {
scanf("%d",&a[i]);X[i]=a[i];
}
sort(X+1,X+1+n);
len=unique(X+1,X+1+n)-X-1;
for(int i=1;i<=n;++i){
int id=getid(a[i]);
ll sum;
for(int j=1;j<=k;++j){
if(j==1) sum=1;
else {
sum=qu(j-1,id-1);
}
add(j,id,sum);
}
}
printf("%d\n",qu(k,len));
}
#include
#define fi first
#define se second
#define mid (l+r>>1)
#define ls (id<<1)
#define rs (id<<1|1)
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll mx[4*N],mi[4*N],sum[4*N],lazy[4*N],a[N];
int n,m;
struct node
{
int l,r,w;
}b[N];
vectoradd[N],del[N];
void build(int id,int l,int r)
{
if(l==r){
scanf("%lld",&a[l]);
mx[id]=mi[id]=a[l];
return ;
}
build(ls,l,mid);
build(rs,mid+1,r);
mx[id]=max(mx[ls],mx[rs]);
mi[id]=min(mi[ls],mi[rs]);
}
void pushdown(int id)
{
if(lazy[id]){
lazy[ls]+=lazy[id];
lazy[rs]+=lazy[id];
mi[ls]+=lazy[id];mi[rs]+=lazy[id];
mx[ls]+=lazy[id];mx[rs]+=lazy[id];
lazy[id]=0;
}
}
void up(int id,int l,int r,int ql,int qr,int w)
{
if(ql<=l&&r<=qr){
mx[id]+=w;
mi[id]+=w;
lazy[id]+=w;
return ;
}
pushdown(id);
if(ql<=mid) up(ls,l,mid,ql,qr,w);
if(qr>mid) up(rs,mid+1,r,ql,qr,w);
mx[id]=max(mx[ls],mx[rs]);
mi[id]=min(mi[ls],mi[rs]);
}
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=m;++i){
int l,r,w;
scanf("%d%d%d",&l,&r,&w);
b[i]={l,r,w};
add[l].push_back(i);
del[r+1].push_back(i);
}
ll ans=mx[1]-mi[1];
for(int i=1;i<=n;++i){
for(int v:add[i]) up(1,1,n,b[v].l,b[v].r,-b[v].w);
for(int v:del[i]) up(1,1,n,b[v].l,b[v].r,b[v].w);
ans=max(ans,mx[1]-mi[1]);
}
printf("%lld\n",ans);
}
注意题目数据存在重边,有重边,那也是一个强连通。。。
#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll powmod(ll a,ll b){a=a%mod;ll res=1;for(;b;b>>=1){
if(b&1) res=res*a%mod;a=a*a%mod;}return res%mod ;}
const int N=2e5+10;
int cnt,dfn[N],low[N],n,m,bcc[N],bccnum;
int dp[N];
vectorG[N],g[N];
stacksta;
void tarjan(int id,int fa)
{
sta.push(id);
dfn[id]=low[id]=++cnt;
int flag=0;
for(int v:G[id]){
if(v == fa && !flag){flag++; continue;}//考虑重边
if(!dfn[v]){
tarjan(v,id);
low[id]=min(low[id],low[v]);
}
else low[id]=min(low[id],dfn[v]);
}
if(low[id]==dfn[id]){
int x;
++bccnum;
do{
x=sta.top(),sta.pop();
bcc[x]=bccnum;
}while(x!=id);
}
}
ll mx,tar;
void DP(int u,int fa)
{
if(dp[u]>mx){
mx=dp[u],tar=u;
}
for(int v:g[u]){
if(v==fa) continue;
dp[v]=dp[u]+1;
DP(v,u);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=n;++i) if(!dfn[i])tarjan(i,0);
for(int i=1;i<=n;++i){
for(int v:G[i]){
if(bcc[i]==bcc[v]) continue;
g[bcc[i]].push_back(bcc[v]);
}
}
DP(1,0);
memset(dp,0,sizeof(dp));
mx=0;
DP(tar,0);
ll ans=(1ll*bccnum-1-mx)*powmod(m+1,mod-2)%mod;
cout<