做法:水题,如果k>=min(n,m) 就是矩阵所有的和
k<=min(n,m)时就是dfs 二进制选取行 然后列 通过排序获得剩余的前k大个。
贪心有wa点,有个不错的数据在我代码最下方
#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=17;
int r[N],c[N],n,m,k,a[N][N],ans,mi,sum,t[N];
int l[N],l1;
bool cmp(int x,int y)
{
return x>y;
}
void dfs(int x,int k)
{
//if(k>m) return ;
if(k==0&&x<=n+1){
ans=max(ans,sum);
return ;
}
if(x>n){
//if(k>m) return ;
if(k==0){
ans=max(ans,sum);
return ;
}
k=min(k,m);
for(int i=1;i<=m;++i) t[i]=c[i];
for(int j=1;j<=l1;++j)
for(int i=1;i<=m;++i) {
t[i]-=a[l[j]][i];
}
sort(t+1,t+1+m,cmp);
int res=sum;
for(int i=1;i<=k;++i){
res+=t[i];
}
if(res==412){
printf("l1:%d\n",l1);
}
ans=max(ans,res);
return ;
}
sum+=r[x];
l[++l1]=x;
dfs(x+1,k-1);
--l1;
sum-=r[x];
dfs(x+1,k);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
mi=min(n,m);
rep(i,1,n){
rep(j,1,m) {
scanf("%d",&a[i][j]);
sum+=a[i][j];
r[i]+=a[i][j];
c[j]+=a[i][j];
}
}
// for(int i=1;i<=m;++i) printf("%d\n",c[i]);
// puts("");
// puts("");
// puts("");
// puts("");
if(k>=mi){
printf("%d\n",sum);
return 0;
}
sum=0;
dfs(1,k);
printf("%d",ans);
return 0;
}
/*
5 6 2
0 0 0 2 2 0
2 1 1 1 1 1
2 1 1 2 2 1
0 0 0 2 2 0
0 0 0 1 1 0
ans=16
*/
做法:简单观察可知,只能往右和往下走,那就随便bfs一下即可。
wa了的看我代码下的一个数据,这个数据能过,基本就能A了。
#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e3+10;
char s[N][N];
int n,m,a[N][N],vis[N][N];
int vs[N][N];
struct node
{
int x,y,step;
bool operator <(const node &o) const{
return o.stepque;
que.push({1,1,0});
vis[1][1]=1;
while(que.size())
{
node now=que.top();que.pop();
//printf("x:%d y:%d t:%d\n",now.x,now.y,now.step);
if(now.x==n&&now.y==m){
printf("%d\n",now.step);
return ;
}
int f=0;
for(int i=0;i<2;++i){
int x=now.x+dir[i][0];
int y=now.y+dir[i][1];
if(x<1||y<1||x>n||y>m) continue;
if(a[x][y]) continue;
vis[x][y]=1;
if(now.step+f
献上题解:
做法:将ai 全部的质因子分解出来,然后按照质因子分块一下,对查询的p也质因子分解一下,离线搞一搞。
枚举p的因子块,同时也在枚举ai的因子块,判断一下ai的因子所在位置i是否在pi因子的范围即可,维护下最大值。
比较的简单 就暂时没有自己打代码了,献上出题人的代码
#include
using namespace std;
const int N=1e5+5;
struct node
{
int l,r,id;
node(int l=0,int r=0,int id=0):l(l),r(r),id(id){}
bool operator<(const node&o)const
{
if(o.r==r) return lv[N];
vectorp[N];
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
for(int j=1;j*j<=x;j++)
if(x%j==0)
{
v[j].push_back(i);
if(x/j!=j) v[x/j].push_back(i);
}
}
for(int i=1;i<=q;i++)
{
int l,r,x;scanf("%d%d%d",&l,&r,&x);
for(int j=1;j*j<=x;j++)
if(x%j==0)
{
p[j].push_back(node(l,r,i));
if(x/j!=j)
p[x/j].push_back(node(l,r,i));
}
}
for(int i=1;i<=100000;i++)
{
if(!v[i].size()) continue;
int k=0;
sort(p[i].begin(),p[i].end());
while(k
题解分析些许复杂,虽然也对,个人感觉复杂了点。
分组个数 应该是i*(k-i+1)-1 因为f(2,2)不算一个路径(题目说的)
应该是
当k为偶数,所有位置的方法数都是奇数,那么树剖上查询就可以了。
当k为奇数,那么就是i为偶数的位置提供答案,按照树上,那么就隔一个顶点贡献一次。
那么树上我们就dfs给标号0 1 相邻的节点标号不同即可
那么当v1 端点是1 那我们只需要在标号为0 的线段树上区间查询即可。
树剖+两颗线段树即可。
#include
using namespace std;
typedef long long ll;
const int N=2e5+10;
vectorG[N];
int a[N];
int sum[2][4*N];
int n,q;
int sz[N],son[N],f[N],d[N],top[N],id[N],cnt;
void dfs1(int u,int fat,int dep)
{
f[u]=fat;
d[u]=dep;
sz[u]=1;
for(int v:G[u])
{
if(v==fat) continue;
dfs1(v,u,dep+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int t)
{
top[u]=t;
id[u]=++cnt;
if(!son[u]) return ;
dfs2(son[u],t);
for(int v:G[u])
{
if(v==son[u]||v==f[u]) continue;
dfs2(v,v);
}
}
void up(int id,int l,int r,int pos,int x,int ty)
{
if(l>r) return ;
if(l==r){
sum[ty][id]=x;
return ;
}
int mid=l+r>>1;
if(pos<=mid) up(id<<1,l,mid,pos,x,ty);
else up(id<<1|1,mid+1,r,pos,x,ty);
sum[ty][id]=(sum[ty][id<<1]^sum[ty][id<<1|1]);
}
int qu(int id,int l,int r,int ql,int qr,int ty){
if(ql<=l&&r<=qr){
return sum[ty][id];
}
int mid=l+r>>1;
int res=0;
if(ql<=mid) res^=qu(id<<1,l,mid,ql,qr,ty);
if(qr>mid) res^=qu(id<<1|1,mid+1,r,ql,qr,ty);
return res;
}
int getsum(int x,int y,int ty)
{
int ans=0,fx=top[x],fy=top[y];
while(fx!=fy){
if(d[fx]>d[fy]){
ans^=qu(1,1,n,id[fx],id[x],ty);
x=f[fx],fx=top[x];
}
else{
ans^=qu(1,1,n,id[fy],id[y],ty);
y=f[fy],fy=top[y];
}
}
if(id[x]>id[y]) ans^=qu(1,1,n,id[y],id[x],ty);
else ans^=qu(1,1,n,id[x],id[y],ty);
return ans;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i) {
scanf("%d",&a[i]);
}
for(int i=1;i<=n-1;++i)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1,0,1);
dfs2(1,1);
for(int i=1;i<=n;++i){
up(1,1,n,id[i],a[i],d[i]%2);
}
while(q--)
{
int ty,u,v;
scanf("%d%d%d",&ty,&u,&v);
if(ty==1){
up(1,1,n,id[u],v,d[u]%2);
}
else{
if(d[u]%2!=d[v]%2){
int ans1=getsum(u,v,d[u]%2);
int ans2=getsum(u,v,(d[u]%2)^1);
printf("%d\n",ans1^ans2);
}
else{
printf("%d\n",getsum(u,v,(d[u]%2)^1));
}
}
}
return 0;
}