wirserd's blog

By wirserd, history, 13 hours ago, In English

Hi everyone,

I'm new to competitive programming and I use C++. I've solved about 40 problems on Codeforces and CSES.

I saw many people use templates like this:

#define ll long long
#define pb push_back
#define all(x) (x).begin(), (x).end()

What I understand so far

Macros just replace text before compilation, so they save typing. For example, sort(all(v)) instead of sort(v.begin(), v.end()).

What confuses me

  1. I read that this macro is dangerous: cpp #define sq(x) x * x sq(a + b) becomes a + b * a + b, which is wrong. I fixed it with ((x) * (x)), but I'm not sure when this kind of bug can appear in a real contest.

  2. I heard that using ll = long long; is better than #define ll long long. Is there a real difference in practice, or is it only about style?

My question: Do you recommend that beginners use macros, or only using ll = long long;? Which macros do you actually use?

Thanks for reading, and sorry for any English mistakes!

  • Vote: I like it
  • -9
  • Vote: I do not like it

»
13 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

well in some contests u wouldnt get to use macros, like olys

so it will be better to practice without macros., and idont think that using macros will give u any benefit in usual contests, macros only matter when u r in blitz contests

  • »
    »
    13 hours ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I think that makes sense, thanks!

»
13 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

you placed 46 th in contest and i think u are not a beginner

  • »
    »
    13 hours ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    Lol bro, maybe I’m a bit past beginner now, but I still have a lot to learn Thanks for the tip!

»
9 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

In general, macros are dangerous because they can be recognized out of context.

For things like 1, it's much safer to define it as a function:

long long sq(long long x) {
    return x * x;
}

For 2, using is a little bit better, although the difference might be tiny. I can think of this:

#define ll long long
int ll x;  // No compile error because "int long long" is a valid type
»
6 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

getting 46th in a div2 is absolutely absurd for someone who solved less than a hundred problems, it is very likely you used ai. People who use AI probably don't have to worry about macros

  • »
    »
    6 hours ago, hide # ^ |
    ← Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    OKay bro. I say in Codeforces and CSES only...

    • »
      »
      »
      5 hours ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      Where else have you solved, give a link to another profile. And also, why would you only give your cf and cses solve counts rather than your main solving profile, that information just feels somewhat useless to give. Also how did you go from failing to solve d2b to solving a-e

      • »
        »
        »
        »
        5 hours ago, hide # ^ |
         
        Vote: I like it 0 Vote: I do not like it

        ,,,, 1. Codechef 2. I mentioned CF and CSES because those are what I practice on the most. 3. In my first contest I had an exam that week and barely participated, so that result doesn't reflect my level.

        I'm happy to explain my solutions to any problem from the last contest.

»
6 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Sometimes macros will make your program considerably slower. For example:

#define max(x,y) ((x)>(y)?(x):(y))

int query(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R) return tr[u].sum;
	int mid=l+r>>1;
	if(R<=mid) return query(u*2,l,mid,L,R);
	if(L>mid) return query(u*2+1,mid+1,r,L,R);
	return max(query(u*2,l,mid,L,R),query(u*2+1,mid+1,r,L,R));
}

This is a simple segtree function that returns the maximum value of the elements in $$$[L,R]$$$. However, its time complexity is $$$O(n)$$$ instead of $$$O(\log n)$$$, since after the max macro is expanded, the query function is called thrice in the max macro instead of twice.

  • »
    »
    5 hours ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    can this macro just be replaced with an inline function?

    inline int max(int a, int b) { return a > b ? a : b; }
    

    I'm asking because the whole problem here is that the macro evaluates its arguments twice, so the query calls get duplicated and the complexity jumps from O(log n) to O(n). With an inline function, each argument is evaluated exactly once before the call, so that duplication goes away. And since it's inline, the compiler should inline it just like the macro, so there shouldn't be any performance cost is that right?

»
5 hours ago, hide # |
 
Vote: I like it +1 Vote: I do not like it

I think you have a 99% chance of cheating

»
5 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

new to cp, solved less than 100 problems and get 46th in a div2 you might be the next tourist or smth

  • »
    »
    5 hours ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I wish to you too!

    I learned C++ and algorithms before starting competitive programming, so I'm not a total beginner in the basics of problem solving.. I still make mistakes in contests, though, and I'm working on that...

»
4 hours ago, hide # |
 
Vote: I like it 0 Vote: I do not like it
  1. of course it can appear in a real contest if you are using that macro, since it is basically wrong. the latter is better but i prefer to make a function to make it safer.
  2. doesn't really matter that much. theres a catch though, the later option doesn't admit functional style casts, i.e. long long (val) does not compile.

anyways macros depend on you, who cares if your macros is wrong if you can make it work. using ll = long long is just another keystroke saver. for me, I usually explore many coding styles since right now I haven't pretty much found one that I really like and will use it for the rest of my CP journey. For me, the macros that usually feels nice to use is probably macros that replace the use of cin >> or cout << since I think << and >> are pretty annoying to type, i.e. using custom IO functions. using ll = long long feels that it saves a lot of time. I just generally use macros to replace stuff that I don't want to type a lot in the moment, I think that is what macros is for.