https://www.luogu.com.cn/problem/P1908
不对结构体进行操作可以AC,代码如下
#include<cstdio>//求逆序对(动态开点权值线段树)
#include<iostream>//https://www.cnblogs.com/IzayoiMiku/p/13997750.html
#include<cstring>
#define lnode tree[node].lson
#define rnode tree[node].rson
using namespace std;
typedef long long ll;
const int N=1e7+10;//动态树最大结点数
const int MAX=1e9;//题中给的值域
struct node {
ll sum;//该点的权值(出现的次数)
int lson,rson;//左子节点,右子节点
} tree[N];
int n,cnt=0,root;//cnt计数变量, 记录开了多少节点
inline int read() {
int s=0,w=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') w*=-1;
c=getchar();
}
while(c>='0' && c<='9') {
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
return s*w;
}
inline void push_up(int node) {//更新父节点
tree[node].sum=tree[lnode].sum+tree[rnode].sum;
}
void update(int &node,int start,int end,int k) { //node是人为规定的编号,所以传引用 k的权值+1
if(!node) { //新建节点
node=++cnt;
}
if(start==end) {
tree[node].sum++;
return ;
}
int mid=start+end>>1;
if(k<=mid) update(lnode,start,mid,k);
else update(rnode,mid+1,end,k);
push_up(node);
}
ll query(int node,int start,int end,int l,int r) {//在以[start,end]为范围的node节点的子树下查询[l,r]出现的次数
if(!node) return 0;//这个节点未被创建, 返回0
if(start>=l && end<=r) return tree[node].sum;//真子集
ll sum=0;
int mid=start+end>>1;
if(l<=mid) sum+=query(lnode,start,mid,l,r);
if(r>mid) sum+=query(rnode,mid+1,end,l,r);
return sum;
}
int main() {//求逆序对
n=read();//序列中有n个数
ll ans=0;
int x;
cnt=root=1;
for(int i=1; i<=n; i++) {
x=read();
if(x+1<=MAX) ans+=query(1,1,MAX,x+1,MAX);//查询当前树中比x大的数的数量,就是x所带来的逆序
update(root,1,MAX,x);
}
printf("%lld\n",ans);
return 0;
}
如果对结构体数组1~N赋值为0,会爆内存,代码我就不列了
于是可以得出结论:结构体数组定义后不会立即分配内存
那么,如果是多次循环,怎么初始化呢?
很简单,for从1到cnt就行了,用多少清空多少
另外,洛谷会等你程序结束才判断输出文件,不同于HDU,所以不要在洛谷开死循环